Update maintainer's address.
[bpt/emacs.git] / lisp / calc / calc-vec.el
CommitLineData
3132f345
CW
1;;; calc-vec.el --- vector functions for Calc
2
58ba2f8f 3;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004,
f0fa15c5 4;; 2005, 2006, 2007 Free Software Foundation, Inc.
3132f345
CW
5
6;; Author: David Gillespie <daveg@synaptics.com>
e8fff8ed 7;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
136211a9
EZ
8
9;; This file is part of GNU Emacs.
10
7c671b23
GM
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
136211a9 16;; GNU Emacs is distributed in the hope that it will be useful,
7c671b23
GM
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GNU Emacs; see the file COPYING. If not, write to the
23;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24;; Boston, MA 02110-1301, USA.
136211a9 25
3132f345 26;;; Commentary:
136211a9 27
3132f345 28;;; Code:
136211a9
EZ
29
30;; This file is autoloaded from calc-ext.el.
136211a9 31
429dae43 32(require 'calc-ext)
136211a9
EZ
33(require 'calc-macs)
34
136211a9
EZ
35(defun calc-display-strings (n)
36 (interactive "P")
37 (calc-wrapper
38 (message (if (calc-change-mode 'calc-display-strings n t t)
3132f345
CW
39 "Displaying vectors of integers as quoted strings"
40 "Displaying vectors of integers normally"))))
136211a9
EZ
41
42
43(defun calc-pack (n)
44 (interactive "P")
45 (calc-wrapper
46 (let* ((nn (if n 1 2))
47 (mode (if n (prefix-numeric-value n) (calc-top-n 1)))
48 (mode (if (and (Math-vectorp mode) (cdr mode)) (cdr mode)
49 (if (integerp mode) mode
50 (error "Packing mode must be an integer or vector of integers"))))
51 (num (calc-pack-size mode))
52 (items (calc-top-list num nn)))
bf77c646 53 (calc-enter-result (+ nn num -1) "pack" (calc-pack-items mode items)))))
136211a9
EZ
54
55(defun calc-pack-size (mode)
56 (cond ((consp mode)
57 (let ((size 1))
58 (while mode
59 (or (integerp (car mode)) (error "Vector of integers expected"))
60 (setq size (* size (calc-pack-size (car mode)))
61 mode (cdr mode)))
62 (if (= size 0)
63 (error "Zero dimensions not allowed")
64 size)))
65 ((>= mode 0) mode)
66 (t (or (cdr (assq mode '((-3 . 3) (-13 . 1) (-14 . 3) (-15 . 6))))
bf77c646 67 2))))
136211a9
EZ
68
69(defun calc-pack-items (mode items)
70 (cond ((consp mode)
71 (if (cdr mode)
72 (let* ((size (calc-pack-size (cdr mode)))
73 (len (length items))
74 (new nil)
75 p row)
76 (while (> len 0)
77 (setq p (nthcdr (1- size) items)
78 row items
79 items (cdr p)
80 len (- len size))
81 (setcdr p nil)
82 (setq new (cons (calc-pack-items (cdr mode) row) new)))
83 (calc-pack-items (car mode) (nreverse new)))
84 (calc-pack-items (car mode) items)))
85 ((>= mode 0)
86 (cons 'vec items))
87 ((= mode -3)
88 (if (and (math-objvecp (car items))
89 (math-objvecp (nth 1 items))
90 (math-objvecp (nth 2 items)))
91 (if (and (math-num-integerp (car items))
92 (math-num-integerp (nth 1 items)))
93 (if (math-realp (nth 2 items))
94 (cons 'hms items)
95 (error "Seconds must be real"))
96 (error "Hours and minutes must be integers"))
97 (math-normalize (list '+
98 (list '+
99 (if (eq calc-angle-mode 'rad)
100 (list '* (car items)
101 '(hms 1 0 0))
102 (car items))
103 (list '* (nth 1 items) '(hms 0 1 0)))
104 (list '* (nth 2 items) '(hms 0 0 1))))))
105 ((= mode -13)
106 (if (math-realp (car items))
107 (cons 'date items)
108 (if (eq (car-safe (car items)) 'date)
109 (car items)
110 (if (math-objvecp (car items))
111 (error "Date value must be real")
112 (cons 'calcFunc-date items)))))
113 ((memq mode '(-14 -15))
114 (let ((p items))
115 (while (and p (math-objvecp (car p)))
116 (or (math-integerp (car p))
117 (error "Components must be integers"))
118 (setq p (cdr p)))
119 (if p
120 (cons 'calcFunc-date items)
121 (list 'date (math-dt-to-date items)))))
122 ((or (eq (car-safe (car items)) 'vec)
123 (eq (car-safe (nth 1 items)) 'vec))
124 (let* ((x (car items))
125 (vx (eq (car-safe x) 'vec))
126 (y (nth 1 items))
127 (vy (eq (car-safe y) 'vec))
128 (z nil)
129 (n (1- (length (if vx x y)))))
130 (and vx vy
131 (/= n (1- (length y)))
132 (error "Vectors must be the same length"))
133 (while (>= (setq n (1- n)) 0)
134 (setq z (cons (calc-pack-items
135 mode
136 (list (if vx (car (setq x (cdr x))) x)
137 (if vy (car (setq y (cdr y))) y)))
138 z)))
139 (cons 'vec (nreverse z))))
140 ((= mode -1)
141 (if (and (math-realp (car items)) (math-realp (nth 1 items)))
142 (cons 'cplx items)
143 (if (and (math-objectp (car items)) (math-objectp (nth 1 items)))
144 (error "Components must be real"))
145 (math-normalize (list '+ (car items)
146 (list '* (nth 1 items) '(cplx 0 1))))))
147 ((= mode -2)
148 (if (and (math-realp (car items)) (math-anglep (nth 1 items)))
149 (cons 'polar items)
150 (if (and (math-objectp (car items)) (math-objectp (nth 1 items)))
151 (error "Components must be real"))
152 (math-normalize (list '* (car items)
153 (if (math-anglep (nth 1 items))
154 (list 'polar 1 (nth 1 items))
155 (list 'calcFunc-exp
156 (list '*
157 (math-to-radians-2
158 (nth 1 items))
159 (list 'polar
160 1
161 (math-quarter-circle
162 nil)))))))))
163 ((= mode -4)
164 (let ((x (car items))
165 (sigma (nth 1 items)))
166 (if (or (math-scalarp x) (not (math-objvecp x)))
167 (if (or (math-anglep sigma) (not (math-objvecp sigma)))
168 (math-make-sdev x sigma)
169 (error "Error component must be real"))
170 (error "Mean component must be real or complex"))))
171 ((= mode -5)
172 (let ((a (car items))
173 (m (nth 1 items)))
174 (if (and (math-anglep a) (math-anglep m))
175 (if (math-posp m)
176 (math-make-mod a m)
177 (error "Modulus must be positive"))
178 (if (and (math-objectp a) (math-objectp m))
179 (error "Components must be real"))
180 (list 'calcFunc-makemod a m))))
181 ((memq mode '(-6 -7 -8 -9))
182 (let ((lo (car items))
183 (hi (nth 1 items)))
184 (if (and (or (math-anglep lo) (eq (car lo) 'date)
185 (not (math-objvecp lo)))
186 (or (math-anglep hi) (eq (car hi) 'date)
187 (not (math-objvecp hi))))
188 (math-make-intv (+ mode 9) lo hi)
189 (error "Components must be real"))))
190 ((eq mode -10)
191 (if (math-zerop (nth 1 items))
192 (error "Denominator must not be zero")
193 (if (and (math-integerp (car items)) (math-integerp (nth 1 items)))
194 (math-normalize (cons 'frac items))
195 (if (and (math-objectp (car items)) (math-objectp (nth 1 items)))
196 (error "Components must be integers"))
197 (cons 'calcFunc-fdiv items))))
198 ((memq mode '(-11 -12))
199 (if (and (math-realp (car items)) (math-integerp (nth 1 items)))
200 (calcFunc-scf (math-float (car items)) (nth 1 items))
201 (if (and (math-objectp (car items)) (math-objectp (nth 1 items)))
202 (error "Components must be integers"))
203 (math-normalize
204 (list 'calcFunc-scf
205 (list 'calcFunc-float (car items))
206 (nth 1 items)))))
207 (t
bf77c646 208 (error "Invalid packing mode: %d" mode))))
136211a9 209
3132f345 210(defvar calc-unpack-with-type nil)
136211a9
EZ
211(defun calc-unpack (mode)
212 (interactive "P")
213 (calc-wrapper
214 (let ((calc-unpack-with-type t))
215 (calc-pop-push-record-list 1 "unpk" (calc-unpack-item
216 (and mode
217 (prefix-numeric-value mode))
bf77c646 218 (calc-top))))))
136211a9
EZ
219
220(defun calc-unpack-type (item)
221 (cond ((eq (car-safe item) 'vec)
222 (1- (length item)))
223 ((eq (car-safe item) 'intv)
224 (- (nth 1 item) 9))
225 (t
226 (or (cdr (assq (car-safe item) '( (cplx . -1) (polar . -2)
227 (hms . -3) (sdev . -4) (mod . -5)
228 (frac . -10) (float . -11)
229 (date . -13) )))
bf77c646 230 (error "Argument must be a composite object")))))
136211a9
EZ
231
232(defun calc-unpack-item (mode item)
233 (cond ((not mode)
234 (if (or (and (not (memq (car-safe item) '(frac float cplx polar vec
235 hms date sdev mod
236 intv)))
237 (math-objvecp item))
238 (eq (car-safe item) 'var))
239 (error "Argument must be a composite object or function call"))
240 (if (eq (car item) 'intv)
241 (cdr (cdr item))
242 (cdr item)))
243 ((> mode 0)
244 (let ((dims nil)
245 type new row)
246 (setq item (list item))
247 (while (> mode 0)
248 (setq type (calc-unpack-type (car item))
249 dims (cons type dims)
250 new (calc-unpack-item nil (car item)))
251 (while (setq item (cdr item))
252 (or (= (calc-unpack-type (car item)) type)
253 (error "Inconsistent types or dimensions in vector elements"))
254 (setq new (append new (calc-unpack-item nil (car item)))))
255 (setq item new
256 mode (1- mode)))
257 (if (cdr dims) (setq dims (list (cons 'vec (nreverse dims)))))
258 (cond ((eq calc-unpack-with-type 'pair)
259 (list (car dims) (cons 'vec item)))
260 (calc-unpack-with-type
261 (append item dims))
262 (t item))))
263 ((eq calc-unpack-with-type 'pair)
264 (let ((calc-unpack-with-type nil))
265 (list mode (cons 'vec (calc-unpack-item mode item)))))
266 ((= mode -3)
267 (if (eq (car-safe item) 'hms)
268 (cdr item)
269 (error "Argument must be an HMS form")))
270 ((= mode -13)
271 (if (eq (car-safe item) 'date)
272 (cdr item)
273 (error "Argument must be a date form")))
274 ((= mode -14)
275 (if (eq (car-safe item) 'date)
276 (math-date-to-dt (math-floor (nth 1 item)))
277 (error "Argument must be a date form")))
278 ((= mode -15)
279 (if (eq (car-safe item) 'date)
280 (append (math-date-to-dt (nth 1 item))
281 (and (not (math-integerp (nth 1 item)))
282 (list 0 0 0)))
283 (error "Argument must be a date form")))
284 ((eq (car-safe item) 'vec)
285 (let ((x nil)
286 (y nil)
287 res)
288 (while (setq item (cdr item))
289 (setq res (calc-unpack-item mode (car item))
290 x (cons (car res) x)
291 y (cons (nth 1 res) y)))
292 (list (cons 'vec (nreverse x))
293 (cons 'vec (nreverse y)))))
294 ((= mode -1)
295 (if (eq (car-safe item) 'cplx)
296 (cdr item)
297 (if (eq (car-safe item) 'polar)
298 (cdr (math-complex item))
299 (if (Math-realp item)
300 (list item 0)
301 (error "Argument must be a complex number")))))
302 ((= mode -2)
303 (if (or (memq (car-safe item) '(cplx polar))
304 (Math-realp item))
305 (cdr (math-polar item))
306 (error "Argument must be a complex number")))
307 ((= mode -4)
308 (if (eq (car-safe item) 'sdev)
309 (cdr item)
310 (list item 0)))
311 ((= mode -5)
312 (if (eq (car-safe item) 'mod)
313 (cdr item)
314 (error "Argument must be a modulo form")))
315 ((memq mode '(-6 -7 -8 -9))
316 (if (eq (car-safe item) 'intv)
317 (cdr (cdr item))
318 (list item item)))
319 ((= mode -10)
320 (if (eq (car-safe item) 'frac)
321 (cdr item)
322 (if (Math-integerp item)
323 (list item 1)
324 (error "Argument must be a rational number"))))
325 ((= mode -11)
326 (if (eq (car-safe item) 'float)
327 (list (nth 1 item) (math-normalize (nth 2 item)))
328 (error "Expected a floating-point number")))
329 ((= mode -12)
330 (if (eq (car-safe item) 'float)
331 (list (calcFunc-mant item) (calcFunc-xpon item))
332 (error "Expected a floating-point number")))
333 (t
bf77c646 334 (error "Invalid unpacking mode: %d" mode))))
136211a9
EZ
335
336(defun calc-diag (n)
337 (interactive "P")
338 (calc-wrapper
339 (calc-enter-result 1 "diag" (if n
340 (list 'calcFunc-diag (calc-top-n 1)
341 (prefix-numeric-value n))
bf77c646 342 (list 'calcFunc-diag (calc-top-n 1))))))
136211a9
EZ
343
344(defun calc-ident (n)
345 (interactive "NDimension of identity matrix = ")
346 (calc-wrapper
347 (calc-enter-result 0 "idn" (if (eq n 0)
348 '(calcFunc-idn 1)
349 (list 'calcFunc-idn 1
bf77c646 350 (prefix-numeric-value n))))))
136211a9
EZ
351
352(defun calc-index (n &optional stack)
353 (interactive "NSize of vector = \nP")
354 (calc-wrapper
355 (if (consp stack)
356 (calc-enter-result 3 "indx" (cons 'calcFunc-index (calc-top-list-n 3)))
357 (calc-enter-result 0 "indx" (list 'calcFunc-index
bf77c646 358 (prefix-numeric-value n))))))
136211a9
EZ
359
360(defun calc-build-vector (n)
361 (interactive "NSize of vector = ")
362 (calc-wrapper
363 (calc-enter-result 1 "bldv" (list 'calcFunc-cvec
364 (calc-top-n 1)
bf77c646 365 (prefix-numeric-value n)))))
136211a9
EZ
366
367(defun calc-cons (arg)
368 (interactive "P")
369 (calc-wrapper
370 (if (calc-is-hyperbolic)
371 (calc-binary-op "rcns" 'calcFunc-rcons arg)
bf77c646 372 (calc-binary-op "cons" 'calcFunc-cons arg))))
136211a9
EZ
373
374
375(defun calc-head (arg)
376 (interactive "P")
377 (calc-wrapper
378 (if (calc-is-inverse)
379 (if (calc-is-hyperbolic)
380 (calc-unary-op "rtai" 'calcFunc-rtail arg)
381 (calc-unary-op "tail" 'calcFunc-tail arg))
382 (if (calc-is-hyperbolic)
383 (calc-unary-op "rhed" 'calcFunc-rhead arg)
bf77c646 384 (calc-unary-op "head" 'calcFunc-head arg)))))
136211a9
EZ
385
386(defun calc-tail (arg)
387 (interactive "P")
388 (calc-invert-func)
bf77c646 389 (calc-head arg))
136211a9
EZ
390
391(defun calc-vlength (arg)
392 (interactive "P")
393 (calc-wrapper
394 (if (calc-is-hyperbolic)
395 (calc-unary-op "dims" 'calcFunc-mdims arg)
bf77c646 396 (calc-unary-op "len" 'calcFunc-vlen arg))))
136211a9
EZ
397
398(defun calc-arrange-vector (n)
399 (interactive "NNumber of columns = ")
400 (calc-wrapper
401 (calc-enter-result 1 "arng" (list 'calcFunc-arrange (calc-top-n 1)
bf77c646 402 (prefix-numeric-value n)))))
136211a9
EZ
403
404(defun calc-vector-find (arg)
405 (interactive "P")
406 (calc-wrapper
407 (let ((func (cons 'calcFunc-find (calc-top-list-n 2))))
408 (calc-enter-result
409 2 "find"
bf77c646 410 (if arg (append func (list (prefix-numeric-value arg))) func)))))
136211a9
EZ
411
412(defun calc-subvector ()
413 (interactive)
414 (calc-wrapper
415 (if (calc-is-inverse)
416 (calc-enter-result 3 "rsvc" (cons 'calcFunc-rsubvec
417 (calc-top-list-n 3)))
bf77c646 418 (calc-enter-result 3 "svec" (cons 'calcFunc-subvec (calc-top-list-n 3))))))
136211a9
EZ
419
420(defun calc-reverse-vector (arg)
421 (interactive "P")
422 (calc-wrapper
bf77c646 423 (calc-unary-op "rev" 'calcFunc-rev arg)))
136211a9
EZ
424
425(defun calc-mask-vector (arg)
426 (interactive "P")
427 (calc-wrapper
bf77c646 428 (calc-binary-op "vmsk" 'calcFunc-vmask arg)))
136211a9
EZ
429
430(defun calc-expand-vector (arg)
431 (interactive "P")
432 (calc-wrapper
433 (if (calc-is-hyperbolic)
434 (calc-enter-result 3 "vexp" (cons 'calcFunc-vexp (calc-top-list-n 3)))
bf77c646 435 (calc-binary-op "vexp" 'calcFunc-vexp arg))))
136211a9
EZ
436
437(defun calc-sort ()
438 (interactive)
439 (calc-slow-wrapper
440 (if (calc-is-inverse)
441 (calc-enter-result 1 "rsrt" (list 'calcFunc-rsort (calc-top-n 1)))
bf77c646 442 (calc-enter-result 1 "sort" (list 'calcFunc-sort (calc-top-n 1))))))
136211a9
EZ
443
444(defun calc-grade ()
445 (interactive)
446 (calc-slow-wrapper
447 (if (calc-is-inverse)
448 (calc-enter-result 1 "rgrd" (list 'calcFunc-rgrade (calc-top-n 1)))
bf77c646 449 (calc-enter-result 1 "grad" (list 'calcFunc-grade (calc-top-n 1))))))
136211a9
EZ
450
451(defun calc-histogram (n)
452 (interactive "NNumber of bins: ")
453 (calc-slow-wrapper
454 (if calc-hyperbolic-flag
455 (calc-enter-result 2 "hist" (list 'calcFunc-histogram
456 (calc-top-n 2)
457 (calc-top-n 1)
458 (prefix-numeric-value n)))
459 (calc-enter-result 1 "hist" (list 'calcFunc-histogram
460 (calc-top-n 1)
bf77c646 461 (prefix-numeric-value n))))))
136211a9
EZ
462
463(defun calc-transpose (arg)
464 (interactive "P")
465 (calc-wrapper
bf77c646 466 (calc-unary-op "trn" 'calcFunc-trn arg)))
136211a9
EZ
467
468(defun calc-conj-transpose (arg)
469 (interactive "P")
470 (calc-wrapper
bf77c646 471 (calc-unary-op "ctrn" 'calcFunc-ctrn arg)))
136211a9
EZ
472
473(defun calc-cross (arg)
474 (interactive "P")
475 (calc-wrapper
bf77c646 476 (calc-binary-op "cros" 'calcFunc-cross arg)))
136211a9
EZ
477
478(defun calc-remove-duplicates (arg)
479 (interactive "P")
480 (calc-wrapper
bf77c646 481 (calc-unary-op "rdup" 'calcFunc-rdup arg)))
136211a9
EZ
482
483(defun calc-set-union (arg)
484 (interactive "P")
485 (calc-wrapper
bf77c646 486 (calc-binary-op "unio" 'calcFunc-vunion arg '(vec) 'calcFunc-rdup)))
136211a9
EZ
487
488(defun calc-set-intersect (arg)
489 (interactive "P")
490 (calc-wrapper
bf77c646 491 (calc-binary-op "intr" 'calcFunc-vint arg '(vec) 'calcFunc-rdup)))
136211a9
EZ
492
493(defun calc-set-difference (arg)
494 (interactive "P")
495 (calc-wrapper
bf77c646 496 (calc-binary-op "diff" 'calcFunc-vdiff arg '(vec) 'calcFunc-rdup)))
136211a9
EZ
497
498(defun calc-set-xor (arg)
499 (interactive "P")
500 (calc-wrapper
bf77c646 501 (calc-binary-op "xor" 'calcFunc-vxor arg '(vec) 'calcFunc-rdup)))
136211a9
EZ
502
503(defun calc-set-complement (arg)
504 (interactive "P")
505 (calc-wrapper
bf77c646 506 (calc-unary-op "cmpl" 'calcFunc-vcompl arg)))
136211a9
EZ
507
508(defun calc-set-floor (arg)
509 (interactive "P")
510 (calc-wrapper
bf77c646 511 (calc-unary-op "vflr" 'calcFunc-vfloor arg)))
136211a9
EZ
512
513(defun calc-set-enumerate (arg)
514 (interactive "P")
515 (calc-wrapper
bf77c646 516 (calc-unary-op "enum" 'calcFunc-venum arg)))
136211a9
EZ
517
518(defun calc-set-span (arg)
519 (interactive "P")
520 (calc-wrapper
bf77c646 521 (calc-unary-op "span" 'calcFunc-vspan arg)))
136211a9
EZ
522
523(defun calc-set-cardinality (arg)
524 (interactive "P")
525 (calc-wrapper
bf77c646 526 (calc-unary-op "card" 'calcFunc-vcard arg)))
136211a9
EZ
527
528(defun calc-unpack-bits (arg)
529 (interactive "P")
530 (calc-wrapper
531 (if (calc-is-inverse)
532 (calc-unary-op "bpck" 'calcFunc-vpack arg)
bf77c646 533 (calc-unary-op "bupk" 'calcFunc-vunpack arg))))
136211a9
EZ
534
535(defun calc-pack-bits (arg)
536 (interactive "P")
537 (calc-invert-func)
bf77c646 538 (calc-unpack-bits arg))
136211a9
EZ
539
540
541(defun calc-rnorm (arg)
542 (interactive "P")
543 (calc-wrapper
bf77c646 544 (calc-unary-op "rnrm" 'calcFunc-rnorm arg)))
136211a9
EZ
545
546(defun calc-cnorm (arg)
547 (interactive "P")
548 (calc-wrapper
bf77c646 549 (calc-unary-op "cnrm" 'calcFunc-cnorm arg)))
136211a9
EZ
550
551(defun calc-mrow (n &optional nn)
552 (interactive "NRow number: \nP")
553 (calc-wrapper
554 (if (consp nn)
555 (calc-enter-result 2 "mrow" (cons 'calcFunc-mrow (calc-top-list-n 2)))
556 (setq n (prefix-numeric-value n))
557 (if (= n 0)
558 (calc-enter-result 1 "getd" (list 'calcFunc-getdiag (calc-top-n 1)))
559 (if (< n 0)
560 (calc-enter-result 1 "rrow" (list 'calcFunc-mrrow
561 (calc-top-n 1) (- n)))
562 (calc-enter-result 1 "mrow" (list 'calcFunc-mrow
bf77c646 563 (calc-top-n 1) n)))))))
136211a9
EZ
564
565(defun calc-mcol (n &optional nn)
566 (interactive "NColumn number: \nP")
567 (calc-wrapper
568 (if (consp nn)
569 (calc-enter-result 2 "mcol" (cons 'calcFunc-mcol (calc-top-list-n 2)))
570 (setq n (prefix-numeric-value n))
571 (if (= n 0)
572 (calc-enter-result 1 "getd" (list 'calcFunc-getdiag (calc-top-n 1)))
573 (if (< n 0)
574 (calc-enter-result 1 "rcol" (list 'calcFunc-mrcol
575 (calc-top-n 1) (- n)))
576 (calc-enter-result 1 "mcol" (list 'calcFunc-mcol
bf77c646 577 (calc-top-n 1) n)))))))
136211a9
EZ
578
579
580;;;; Vectors.
581
582(defun calcFunc-mdims (m)
583 (or (math-vectorp m)
584 (math-reject-arg m 'vectorp))
bf77c646 585 (cons 'vec (math-mat-dimens m)))
136211a9
EZ
586
587
588;;; Apply a function elementwise to vector A. [V X V; N X N] [Public]
589(defun math-map-vec (f a)
590 (if (math-vectorp a)
591 (cons 'vec (mapcar f (cdr a)))
bf77c646 592 (funcall f a)))
136211a9
EZ
593
594(defun math-dimension-error ()
595 (calc-record-why "*Dimension error")
bf77c646 596 (signal 'wrong-type-argument nil))
136211a9
EZ
597
598
599;;; Build a vector out of a list of objects. [Public]
600(defun calcFunc-vec (&rest objs)
bf77c646 601 (cons 'vec objs))
136211a9
EZ
602
603
604;;; Build a constant vector or matrix. [Public]
605(defun calcFunc-cvec (obj &rest dims)
bf77c646 606 (math-make-vec-dimen obj dims))
136211a9
EZ
607
608(defun math-make-vec-dimen (obj dims)
609 (if dims
610 (if (natnump (car dims))
611 (if (or (cdr dims)
612 (not (math-numberp obj)))
613 (cons 'vec (copy-sequence
614 (make-list (car dims)
615 (math-make-vec-dimen obj (cdr dims)))))
616 (cons 'vec (make-list (car dims) obj)))
617 (math-reject-arg (car dims) 'fixnatnump))
bf77c646 618 obj))
136211a9
EZ
619
620(defun calcFunc-head (vec)
621 (if (and (Math-vectorp vec)
622 (cdr vec))
623 (nth 1 vec)
624 (calc-record-why 'vectorp vec)
bf77c646 625 (list 'calcFunc-head vec)))
136211a9
EZ
626
627(defun calcFunc-tail (vec)
628 (if (and (Math-vectorp vec)
629 (cdr vec))
630 (cons 'vec (cdr (cdr vec)))
631 (calc-record-why 'vectorp vec)
bf77c646 632 (list 'calcFunc-tail vec)))
136211a9
EZ
633
634(defun calcFunc-cons (head tail)
635 (if (Math-vectorp tail)
636 (cons 'vec (cons head (cdr tail)))
637 (calc-record-why 'vectorp tail)
bf77c646 638 (list 'calcFunc-cons head tail)))
136211a9
EZ
639
640(defun calcFunc-rhead (vec)
641 (if (and (Math-vectorp vec)
642 (cdr vec))
643 (let ((vec (copy-sequence vec)))
644 (setcdr (nthcdr (- (length vec) 2) vec) nil)
645 vec)
646 (calc-record-why 'vectorp vec)
bf77c646 647 (list 'calcFunc-rhead vec)))
136211a9
EZ
648
649(defun calcFunc-rtail (vec)
650 (if (and (Math-vectorp vec)
651 (cdr vec))
652 (nth (1- (length vec)) vec)
653 (calc-record-why 'vectorp vec)
bf77c646 654 (list 'calcFunc-rtail vec)))
136211a9
EZ
655
656(defun calcFunc-rcons (head tail)
657 (if (Math-vectorp head)
658 (append head (list tail))
659 (calc-record-why 'vectorp head)
bf77c646 660 (list 'calcFunc-rcons head tail)))
136211a9
EZ
661
662
663
664;;; Apply a function elementwise to vectors A and B. [O X O O] [Public]
665(defun math-map-vec-2 (f a b)
666 (if (math-vectorp a)
667 (if (math-vectorp b)
668 (let ((v nil))
669 (while (setq a (cdr a))
670 (or (setq b (cdr b))
671 (math-dimension-error))
672 (setq v (cons (funcall f (car a) (car b)) v)))
673 (if a (math-dimension-error))
674 (cons 'vec (nreverse v)))
675 (let ((v nil))
676 (while (setq a (cdr a))
677 (setq v (cons (funcall f (car a) b) v)))
678 (cons 'vec (nreverse v))))
679 (if (math-vectorp b)
680 (let ((v nil))
681 (while (setq b (cdr b))
682 (setq v (cons (funcall f a (car b)) v)))
683 (cons 'vec (nreverse v)))
bf77c646 684 (funcall f a b))))
136211a9
EZ
685
686
687
688;;; "Reduce" a function over a vector (left-associatively). [O X V] [Public]
689(defun math-reduce-vec (f a)
690 (if (math-vectorp a)
691 (if (cdr a)
692 (let ((accum (car (setq a (cdr a)))))
693 (while (setq a (cdr a))
694 (setq accum (funcall f accum (car a))))
695 accum)
696 0)
bf77c646 697 a))
136211a9
EZ
698
699;;; Reduce a function over the columns of matrix A. [V X V] [Public]
700(defun math-reduce-cols (f a)
701 (if (math-matrixp a)
702 (cons 'vec (math-reduce-cols-col-step f (cdr a) 1 (length (nth 1 a))))
bf77c646 703 a))
136211a9
EZ
704
705(defun math-reduce-cols-col-step (f a col cols)
706 (and (< col cols)
707 (cons (math-reduce-cols-row-step f (nth col (car a)) col (cdr a))
bf77c646 708 (math-reduce-cols-col-step f a (1+ col) cols))))
136211a9
EZ
709
710(defun math-reduce-cols-row-step (f tot col a)
711 (if a
712 (math-reduce-cols-row-step f
713 (funcall f tot (nth col (car a)))
714 col
715 (cdr a))
bf77c646 716 tot))
136211a9
EZ
717
718
719
720(defun math-dot-product (a b)
721 (if (setq a (cdr a) b (cdr b))
722 (let ((accum (math-mul (car a) (car b))))
723 (while (setq a (cdr a) b (cdr b))
724 (setq accum (math-add accum (math-mul (car a) (car b)))))
725 accum)
bf77c646 726 0))
136211a9
EZ
727
728
729;;; Return the number of elements in vector V. [Public]
730(defun calcFunc-vlen (v)
731 (if (math-vectorp v)
732 (1- (length v))
733 (if (math-objectp v)
734 0
bf77c646 735 (list 'calcFunc-vlen v))))
136211a9
EZ
736
737;;; Get the Nth row of a matrix.
738(defun calcFunc-mrow (mat n) ; [Public]
739 (if (Math-vectorp n)
740 (math-map-vec (function (lambda (x) (calcFunc-mrow mat x))) n)
741 (if (and (eq (car-safe n) 'intv) (math-constp n))
742 (calcFunc-subvec mat
743 (math-add (nth 2 n) (if (memq (nth 1 n) '(2 3)) 0 1))
744 (math-add (nth 3 n) (if (memq (nth 1 n) '(1 3)) 1 0)))
745 (or (and (integerp (setq n (math-check-integer n)))
746 (> n 0))
747 (math-reject-arg n 'fixposintp))
748 (or (Math-vectorp mat)
749 (math-reject-arg mat 'vectorp))
750 (or (nth n mat)
bf77c646 751 (math-reject-arg n "*Index out of range")))))
136211a9
EZ
752
753(defun calcFunc-subscr (mat n &optional m)
754 (setq mat (calcFunc-mrow mat n))
755 (if m
756 (if (math-num-integerp n)
757 (calcFunc-mrow mat m)
758 (calcFunc-mcol mat m))
bf77c646 759 mat))
136211a9
EZ
760
761;;; Get the Nth column of a matrix.
762(defun math-mat-col (mat n)
bf77c646 763 (cons 'vec (mapcar (function (lambda (x) (elt x n))) (cdr mat))))
136211a9
EZ
764
765(defun calcFunc-mcol (mat n) ; [Public]
766 (if (Math-vectorp n)
767 (calcFunc-trn
768 (math-map-vec (function (lambda (x) (calcFunc-mcol mat x))) n))
769 (if (and (eq (car-safe n) 'intv) (math-constp n))
770 (if (math-matrixp mat)
771 (math-map-vec (function (lambda (x) (calcFunc-mrow x n))) mat)
772 (calcFunc-mrow mat n))
773 (or (and (integerp (setq n (math-check-integer n)))
774 (> n 0))
775 (math-reject-arg n 'fixposintp))
776 (or (Math-vectorp mat)
777 (math-reject-arg mat 'vectorp))
778 (or (if (math-matrixp mat)
779 (and (< n (length (nth 1 mat)))
780 (math-mat-col mat n))
781 (nth n mat))
bf77c646 782 (math-reject-arg n "*Index out of range")))))
136211a9
EZ
783
784;;; Remove the Nth row from a matrix.
785(defun math-mat-less-row (mat n)
786 (if (<= n 0)
787 (cdr mat)
788 (cons (car mat)
bf77c646 789 (math-mat-less-row (cdr mat) (1- n)))))
136211a9
EZ
790
791(defun calcFunc-mrrow (mat n) ; [Public]
792 (and (integerp (setq n (math-check-integer n)))
793 (> n 0)
794 (< n (length mat))
bf77c646 795 (math-mat-less-row mat n)))
136211a9
EZ
796
797;;; Remove the Nth column from a matrix.
798(defun math-mat-less-col (mat n)
799 (cons 'vec (mapcar (function (lambda (x) (math-mat-less-row x n)))
bf77c646 800 (cdr mat))))
136211a9
EZ
801
802(defun calcFunc-mrcol (mat n) ; [Public]
803 (and (integerp (setq n (math-check-integer n)))
804 (> n 0)
805 (if (math-matrixp mat)
806 (and (< n (length (nth 1 mat)))
807 (math-mat-less-col mat n))
bf77c646 808 (math-mat-less-row mat n))))
136211a9
EZ
809
810(defun calcFunc-getdiag (mat) ; [Public]
811 (if (math-square-matrixp mat)
812 (cons 'vec (math-get-diag-step (cdr mat) 1))
813 (calc-record-why 'square-matrixp mat)
bf77c646 814 (list 'calcFunc-getdiag mat)))
136211a9
EZ
815
816(defun math-get-diag-step (row n)
817 (and row
818 (cons (nth n (car row))
bf77c646 819 (math-get-diag-step (cdr row) (1+ n)))))
136211a9
EZ
820
821(defun math-transpose (mat) ; [Public]
822 (let ((m nil)
823 (col (length (nth 1 mat))))
824 (while (> (setq col (1- col)) 0)
825 (setq m (cons (math-mat-col mat col) m)))
bf77c646 826 (cons 'vec m)))
136211a9
EZ
827
828(defun calcFunc-trn (mat)
829 (if (math-vectorp mat)
830 (if (math-matrixp mat)
831 (math-transpose mat)
832 (math-col-matrix mat))
833 (if (math-numberp mat)
834 mat
bf77c646 835 (math-reject-arg mat 'matrixp))))
136211a9
EZ
836
837(defun calcFunc-ctrn (mat)
bf77c646 838 (calcFunc-conj (calcFunc-trn mat)))
136211a9
EZ
839
840(defun calcFunc-pack (mode els)
841 (or (Math-vectorp els) (math-reject-arg els 'vectorp))
842 (if (and (Math-vectorp mode) (cdr mode))
843 (setq mode (cdr mode))
844 (or (integerp mode) (math-reject-arg mode 'fixnump)))
845 (condition-case err
846 (if (= (calc-pack-size mode) (1- (length els)))
847 (calc-pack-items mode (cdr els))
848 (math-reject-arg els "*Wrong number of elements"))
bf77c646 849 (error (math-reject-arg els (nth 1 err)))))
136211a9
EZ
850
851(defun calcFunc-unpack (mode thing)
852 (or (integerp mode) (math-reject-arg mode 'fixnump))
853 (condition-case err
854 (cons 'vec (calc-unpack-item mode thing))
bf77c646 855 (error (math-reject-arg thing (nth 1 err)))))
136211a9
EZ
856
857(defun calcFunc-unpackt (mode thing)
858 (let ((calc-unpack-with-type 'pair))
bf77c646 859 (calcFunc-unpack mode thing)))
136211a9
EZ
860
861(defun calcFunc-arrange (vec cols) ; [Public]
862 (setq cols (math-check-fixnum cols t))
863 (if (math-vectorp vec)
864 (let* ((flat (math-flatten-vector vec))
865 (mat (list 'vec))
866 next)
867 (if (<= cols 0)
868 (nconc mat flat)
869 (while (>= (length flat) cols)
870 (setq next (nthcdr cols flat))
871 (setcdr (nthcdr (1- cols) flat) nil)
872 (setq mat (nconc mat (list (cons 'vec flat)))
873 flat next))
874 (if flat
875 (setq mat (nconc mat (list (cons 'vec flat)))))
bf77c646 876 mat))))
136211a9
EZ
877
878(defun math-flatten-vector (vec) ; [L V]
879 (if (math-vectorp vec)
880 (apply 'append (mapcar 'math-flatten-vector (cdr vec)))
bf77c646 881 (list vec)))
136211a9
EZ
882
883(defun calcFunc-vconcat (a b)
bf77c646 884 (math-normalize (list '| a b)))
136211a9
EZ
885
886(defun calcFunc-vconcatrev (a b)
bf77c646 887 (math-normalize (list '| b a)))
136211a9
EZ
888
889(defun calcFunc-append (v1 v2)
890 (if (and (math-vectorp v1) (math-vectorp v2))
891 (append v1 (cdr v2))
bf77c646 892 (list 'calcFunc-append v1 v2)))
136211a9
EZ
893
894(defun calcFunc-appendrev (v1 v2)
bf77c646 895 (calcFunc-append v2 v1))
136211a9
EZ
896
897
898;;; Copy a matrix. [Public]
899(defun math-copy-matrix (m)
900 (if (math-vectorp (nth 1 m))
901 (cons 'vec (mapcar 'copy-sequence (cdr m)))
bf77c646 902 (copy-sequence m)))
136211a9
EZ
903
904;;; Convert a scalar or vector into an NxN diagonal matrix. [Public]
905(defun calcFunc-diag (a &optional n)
906 (and n (not (integerp n))
907 (setq n (math-check-fixnum n)))
908 (if (math-vectorp a)
909 (if (and n (/= (length a) (1+ n)))
910 (list 'calcFunc-diag a n)
911 (if (math-matrixp a)
912 (if (and n (/= (length (elt a 1)) (1+ n)))
913 (list 'calcFunc-diag a n)
914 a)
915 (cons 'vec (math-diag-step (cdr a) 0 (1- (length a))))))
916 (if n
917 (cons 'vec (math-diag-step (make-list n a) 0 n))
bf77c646 918 (list 'calcFunc-diag a))))
136211a9
EZ
919
920(defun calcFunc-idn (a &optional n)
921 (if n
922 (if (math-vectorp a)
923 (math-reject-arg a 'numberp)
924 (calcFunc-diag a n))
925 (if (integerp calc-matrix-mode)
926 (calcFunc-idn a calc-matrix-mode)
bf77c646 927 (list 'calcFunc-idn a))))
136211a9
EZ
928
929(defun math-mimic-ident (a m)
930 (if (math-square-matrixp m)
931 (calcFunc-idn a (1- (length m)))
932 (if (math-vectorp m)
933 (if (math-zerop a)
934 (cons 'vec (mapcar (function (lambda (x)
935 (if (math-vectorp x)
936 (math-mimic-ident a x)
937 a)))
938 (cdr m)))
939 (math-dimension-error))
bf77c646 940 (calcFunc-idn a))))
136211a9
EZ
941
942(defun math-diag-step (a n m)
943 (if (< n m)
944 (cons (cons 'vec
945 (nconc (make-list n 0)
946 (cons (car a)
947 (make-list (1- (- m n)) 0))))
948 (math-diag-step (cdr a) (1+ n) m))
bf77c646 949 nil))
136211a9
EZ
950
951;;; Create a vector of consecutive integers. [Public]
952(defun calcFunc-index (n &optional start incr)
953 (if (math-messy-integerp n)
954 (math-float (calcFunc-index (math-trunc n) start incr))
955 (and (not (integerp n))
956 (setq n (math-check-fixnum n)))
957 (let ((vec nil))
958 (if start
959 (progn
960 (if (>= n 0)
961 (while (>= (setq n (1- n)) 0)
962 (setq vec (cons start vec)
963 start (math-add start (or incr 1))))
964 (while (<= (setq n (1+ n)) 0)
965 (setq vec (cons start vec)
966 start (math-mul start (or incr 2)))))
967 (setq vec (nreverse vec)))
968 (if (>= n 0)
969 (while (> n 0)
970 (setq vec (cons n vec)
971 n (1- n)))
972 (let ((i -1))
973 (while (>= i n)
974 (setq vec (cons i vec)
975 i (1- i))))))
bf77c646 976 (cons 'vec vec))))
136211a9
EZ
977
978;;; Find an element in a vector.
979(defun calcFunc-find (vec x &optional start)
980 (setq start (if start (math-check-fixnum start t) 1))
981 (if (< start 1) (math-reject-arg start 'posp))
982 (setq vec (nthcdr start vec))
983 (let ((n start))
984 (while (and vec (not (Math-equal x (car vec))))
985 (setq n (1+ n)
986 vec (cdr vec)))
bf77c646 987 (if vec n 0)))
136211a9
EZ
988
989;;; Return a subvector of a vector.
990(defun calcFunc-subvec (vec start &optional end)
991 (setq start (math-check-fixnum start t)
992 end (math-check-fixnum (or end 0) t))
993 (or (math-vectorp vec) (math-reject-arg vec 'vectorp))
994 (let ((len (1- (length vec))))
995 (if (<= start 0)
996 (setq start (+ len start 1)))
997 (if (<= end 0)
998 (setq end (+ len end 1)))
999 (if (or (> start len)
1000 (<= end start))
1001 '(vec)
1002 (setq vec (nthcdr start vec))
1003 (if (<= end len)
1004 (let ((chop (nthcdr (- end start 1) (setq vec (copy-sequence vec)))))
1005 (setcdr chop nil)))
bf77c646 1006 (cons 'vec vec))))
136211a9
EZ
1007
1008;;; Remove a subvector from a vector.
1009(defun calcFunc-rsubvec (vec start &optional end)
1010 (setq start (math-check-fixnum start t)
1011 end (math-check-fixnum (or end 0) t))
1012 (or (math-vectorp vec) (math-reject-arg vec 'vectorp))
1013 (let ((len (1- (length vec))))
1014 (if (<= start 0)
1015 (setq start (+ len start 1)))
1016 (if (<= end 0)
1017 (setq end (+ len end 1)))
1018 (if (or (> start len)
1019 (<= end start))
1020 vec
1021 (let ((tail (nthcdr end vec))
1022 (chop (nthcdr (1- start) (setq vec (copy-sequence vec)))))
1023 (setcdr chop nil)
bf77c646 1024 (append vec tail)))))
136211a9
EZ
1025
1026;;; Reverse the order of the elements of a vector.
1027(defun calcFunc-rev (vec)
1028 (if (math-vectorp vec)
1029 (cons 'vec (reverse (cdr vec)))
bf77c646 1030 (math-reject-arg vec 'vectorp)))
136211a9
EZ
1031
1032;;; Compress a vector according to a mask vector.
1033(defun calcFunc-vmask (mask vec)
1034 (if (math-numberp mask)
1035 (if (math-zerop mask)
1036 '(vec)
1037 vec)
1038 (or (math-vectorp mask) (math-reject-arg mask 'vectorp))
1039 (or (math-constp mask) (math-reject-arg mask 'constp))
1040 (or (math-vectorp vec) (math-reject-arg vec 'vectorp))
1041 (or (= (length mask) (length vec)) (math-dimension-error))
1042 (let ((new nil))
1043 (while (setq mask (cdr mask) vec (cdr vec))
1044 (or (math-zerop (car mask))
1045 (setq new (cons (car vec) new))))
bf77c646 1046 (cons 'vec (nreverse new)))))
136211a9
EZ
1047
1048;;; Expand a vector according to a mask vector.
1049(defun calcFunc-vexp (mask vec &optional filler)
1050 (or (math-vectorp mask) (math-reject-arg mask 'vectorp))
1051 (or (math-constp mask) (math-reject-arg mask 'constp))
1052 (or (math-vectorp vec) (math-reject-arg vec 'vectorp))
1053 (let ((new nil)
1054 (fvec (and filler (math-vectorp filler))))
1055 (while (setq mask (cdr mask))
1056 (if (math-zerop (car mask))
1057 (setq new (cons (or (if fvec
1058 (car (setq filler (cdr filler)))
1059 filler)
1060 (car mask)) new))
1061 (setq vec (cdr vec)
1062 new (cons (or (car vec) (car mask)) new))))
bf77c646 1063 (cons 'vec (nreverse new))))
136211a9
EZ
1064
1065
1066;;; Compute the row and column norms of a vector or matrix. [Public]
1067(defun calcFunc-rnorm (a)
1068 (if (and (Math-vectorp a)
1069 (math-constp a))
1070 (if (math-matrixp a)
1071 (math-reduce-vec 'math-max (math-map-vec 'calcFunc-cnorm a))
1072 (math-reduce-vec 'math-max (math-map-vec 'math-abs a)))
1073 (calc-record-why 'vectorp a)
bf77c646 1074 (list 'calcFunc-rnorm a)))
136211a9
EZ
1075
1076(defun calcFunc-cnorm (a)
1077 (if (and (Math-vectorp a)
1078 (math-constp a))
1079 (if (math-matrixp a)
1080 (math-reduce-vec 'math-max
1081 (math-reduce-cols 'math-add-abs a))
1082 (math-reduce-vec 'math-add-abs a))
1083 (calc-record-why 'vectorp a)
bf77c646 1084 (list 'calcFunc-cnorm a)))
136211a9
EZ
1085
1086(defun math-add-abs (a b)
bf77c646 1087 (math-add (math-abs a) (math-abs b)))
136211a9
EZ
1088
1089
1090;;; Sort the elements of a vector into increasing order.
1091(defun calcFunc-sort (vec) ; [Public]
1092 (if (math-vectorp vec)
1093 (cons 'vec (sort (copy-sequence (cdr vec)) 'math-beforep))
bf77c646 1094 (math-reject-arg vec 'vectorp)))
136211a9
EZ
1095
1096(defun calcFunc-rsort (vec) ; [Public]
1097 (if (math-vectorp vec)
1098 (cons 'vec (nreverse (sort (copy-sequence (cdr vec)) 'math-beforep)))
bf77c646 1099 (math-reject-arg vec 'vectorp)))
136211a9 1100
866ebaa9
JB
1101;; The variable math-grade-vec is local to calcFunc-grade and
1102;; calcFunc-rgrade, but is used by math-grade-beforep, which is called
1103;; by calcFunc-grade and calcFunc-rgrade.
1104(defvar math-grade-vec)
1105
1106(defun calcFunc-grade (math-grade-vec)
1107 (if (math-vectorp math-grade-vec)
1108 (let* ((len (1- (length math-grade-vec))))
136211a9 1109 (cons 'vec (sort (cdr (calcFunc-index len)) 'math-grade-beforep)))
866ebaa9 1110 (math-reject-arg math-grade-vec 'vectorp)))
136211a9 1111
866ebaa9
JB
1112(defun calcFunc-rgrade (math-grade-vec)
1113 (if (math-vectorp math-grade-vec)
1114 (let* ((len (1- (length math-grade-vec))))
136211a9
EZ
1115 (cons 'vec (nreverse (sort (cdr (calcFunc-index len))
1116 'math-grade-beforep))))
866ebaa9 1117 (math-reject-arg math-grade-vec 'vectorp)))
136211a9
EZ
1118
1119(defun math-grade-beforep (i j)
866ebaa9 1120 (math-beforep (nth i math-grade-vec) (nth j math-grade-vec)))
136211a9
EZ
1121
1122
1123;;; Compile a histogram of data from a vector.
1124(defun calcFunc-histogram (vec wts &optional n)
1125 (or n (setq n wts wts 1))
1126 (or (Math-vectorp vec)
1127 (math-reject-arg vec 'vectorp))
1128 (if (Math-vectorp wts)
1129 (or (= (length vec) (length wts))
1130 (math-dimension-error)))
1131 (or (natnump n)
1132 (math-reject-arg n 'fixnatnump))
1133 (let ((res (make-vector n 0))
1134 (vp vec)
1135 (wvec (Math-vectorp wts))
1136 (wp wts)
1137 bin)
1138 (while (setq vp (cdr vp))
1139 (setq bin (car vp))
1140 (or (natnump bin)
1141 (setq bin (math-floor bin)))
1142 (and (natnump bin)
1143 (< bin n)
1144 (aset res bin (math-add (aref res bin)
1145 (if wvec (car (setq wp (cdr wp))) wts)))))
bf77c646 1146 (cons 'vec (append res nil))))
136211a9
EZ
1147
1148
1149;;; Set operations.
1150
1151(defun calcFunc-vunion (a b)
1152 (if (Math-objectp a)
1153 (setq a (list 'vec a))
1154 (or (math-vectorp a) (math-reject-arg a 'vectorp)))
1155 (if (Math-objectp b)
1156 (setq b (list b))
1157 (or (math-vectorp b) (math-reject-arg b 'vectorp))
1158 (setq b (cdr b)))
bf77c646 1159 (calcFunc-rdup (append a b)))
136211a9
EZ
1160
1161(defun calcFunc-vint (a b)
1162 (if (and (math-simple-set a) (math-simple-set b))
1163 (progn
1164 (setq a (cdr (calcFunc-rdup a)))
1165 (setq b (cdr (calcFunc-rdup b)))
1166 (let ((vec (list 'vec)))
1167 (while (and a b)
1168 (if (math-beforep (car a) (car b))
1169 (setq a (cdr a))
1170 (if (Math-equal (car a) (car b))
1171 (setq vec (cons (car a) vec)
1172 a (cdr a)))
1173 (setq b (cdr b))))
1174 (nreverse vec)))
1175 (calcFunc-vcompl (calcFunc-vunion (calcFunc-vcompl a)
bf77c646 1176 (calcFunc-vcompl b)))))
136211a9
EZ
1177
1178(defun calcFunc-vdiff (a b)
1179 (if (and (math-simple-set a) (math-simple-set b))
1180 (progn
1181 (setq a (cdr (calcFunc-rdup a)))
1182 (setq b (cdr (calcFunc-rdup b)))
1183 (let ((vec (list 'vec)))
1184 (while a
1185 (while (and b (math-beforep (car b) (car a)))
1186 (setq b (cdr b)))
1187 (if (and b (Math-equal (car a) (car b)))
1188 (setq a (cdr a)
1189 b (cdr b))
1190 (setq vec (cons (car a) vec)
1191 a (cdr a))))
1192 (nreverse vec)))
bf77c646 1193 (calcFunc-vcompl (calcFunc-vunion (calcFunc-vcompl a) b))))
136211a9
EZ
1194
1195(defun calcFunc-vxor (a b)
1196 (if (and (math-simple-set a) (math-simple-set b))
1197 (progn
1198 (setq a (cdr (calcFunc-rdup a)))
1199 (setq b (cdr (calcFunc-rdup b)))
1200 (let ((vec (list 'vec)))
1201 (while (or a b)
1202 (if (and a
1203 (or (not b)
1204 (math-beforep (car a) (car b))))
1205 (setq vec (cons (car a) vec)
1206 a (cdr a))
1207 (if (and a (Math-equal (car a) (car b)))
1208 (setq a (cdr a))
1209 (setq vec (cons (car b) vec)))
1210 (setq b (cdr b))))
1211 (nreverse vec)))
1212 (let ((ca (calcFunc-vcompl a))
1213 (cb (calcFunc-vcompl b)))
1214 (calcFunc-vunion (calcFunc-vcompl (calcFunc-vunion ca b))
bf77c646 1215 (calcFunc-vcompl (calcFunc-vunion a cb))))))
136211a9
EZ
1216
1217(defun calcFunc-vcompl (a)
1218 (setq a (math-prepare-set a))
1219 (let ((vec (list 'vec))
1220 (prev '(neg (var inf var-inf)))
1221 (closed 2))
1222 (while (setq a (cdr a))
1223 (or (and (equal (nth 2 (car a)) '(neg (var inf var-inf)))
1224 (memq (nth 1 (car a)) '(2 3)))
1225 (setq vec (cons (list 'intv
1226 (+ closed
1227 (if (memq (nth 1 (car a)) '(0 1)) 1 0))
1228 prev
1229 (nth 2 (car a)))
1230 vec)))
1231 (setq prev (nth 3 (car a))
1232 closed (if (memq (nth 1 (car a)) '(0 2)) 2 0)))
1233 (or (and (equal prev '(var inf var-inf))
1234 (= closed 0))
1235 (setq vec (cons (list 'intv (+ closed 1)
1236 prev '(var inf var-inf))
1237 vec)))
bf77c646 1238 (math-clean-set (nreverse vec))))
136211a9
EZ
1239
1240(defun calcFunc-vspan (a)
1241 (setq a (math-prepare-set a))
1242 (if (cdr a)
1243 (let ((last (nth (1- (length a)) a)))
1244 (math-make-intv (+ (logand (nth 1 (nth 1 a)) 2)
1245 (logand (nth 1 last) 1))
1246 (nth 2 (nth 1 a))
1247 (nth 3 last)))
bf77c646 1248 '(intv 2 0 0)))
136211a9
EZ
1249
1250(defun calcFunc-vfloor (a &optional always-vec)
1251 (setq a (math-prepare-set a))
1252 (let ((vec (list 'vec)) (p a) (prev nil) b mask)
1253 (while (setq p (cdr p))
1254 (setq mask (nth 1 (car p))
1255 a (nth 2 (car p))
1256 b (nth 3 (car p)))
1257 (and (memq mask '(0 1))
1258 (not (math-infinitep a))
1259 (setq mask (logior mask 2))
1260 (math-num-integerp a)
1261 (setq a (math-add a 1)))
1262 (setq a (math-ceiling a))
1263 (and (memq mask '(0 2))
1264 (not (math-infinitep b))
1265 (setq mask (logior mask 1))
1266 (math-num-integerp b)
1267 (setq b (math-sub b 1)))
1268 (setq b (math-floor b))
1269 (if (and prev (Math-equal (math-sub a 1) (nth 3 prev)))
1270 (setcar (nthcdr 3 prev) b)
1271 (or (Math-lessp b a)
1272 (setq vec (cons (setq prev (list 'intv mask a b)) vec)))))
1273 (setq vec (nreverse vec))
bf77c646 1274 (math-clean-set vec always-vec)))
136211a9
EZ
1275
1276(defun calcFunc-vcard (a)
1277 (setq a (calcFunc-vfloor a t))
1278 (or (math-constp a) (math-reject-arg a "*Set must be finite"))
1279 (let ((count 0))
1280 (while (setq a (cdr a))
1281 (if (eq (car-safe (car a)) 'intv)
1282 (setq count (math-add count (math-sub (nth 3 (car a))
1283 (nth 2 (car a))))))
1284 (setq count (math-add count 1)))
bf77c646 1285 count))
136211a9
EZ
1286
1287(defun calcFunc-venum (a)
1288 (setq a (calcFunc-vfloor a t))
1289 (or (math-constp a) (math-reject-arg a "*Set must be finite"))
1290 (let ((p a) next)
1291 (while (cdr p)
1292 (setq next (cdr p))
1293 (if (eq (car-safe (nth 1 p)) 'intv)
1294 (setcdr p (nconc (cdr (calcFunc-index (math-add
1295 (math-sub (nth 3 (nth 1 p))
1296 (nth 2 (nth 1 p)))
1297 1)
1298 (nth 2 (nth 1 p))))
1299 (cdr (cdr p)))))
1300 (setq p next))
bf77c646 1301 a))
136211a9
EZ
1302
1303(defun calcFunc-vpack (a)
1304 (setq a (calcFunc-vfloor a t))
1305 (if (and (cdr a)
1306 (math-negp (if (eq (car-safe (nth 1 a)) 'intv)
1307 (nth 2 (nth 1 a))
1308 (nth 1 a))))
1309 (math-reject-arg (nth 1 a) 'posp))
1310 (let ((accum 0))
1311 (while (setq a (cdr a))
1312 (if (eq (car-safe (car a)) 'intv)
1313 (if (equal (nth 3 (car a)) '(var inf var-inf))
1314 (setq accum (math-sub accum
1315 (math-power-of-2 (nth 2 (car a)))))
1316 (setq accum (math-add accum
1317 (math-sub
1318 (math-power-of-2 (1+ (nth 3 (car a))))
1319 (math-power-of-2 (nth 2 (car a)))))))
1320 (setq accum (math-add accum (math-power-of-2 (car a))))))
bf77c646 1321 accum))
136211a9
EZ
1322
1323(defun calcFunc-vunpack (a &optional w)
1324 (or (math-num-integerp a) (math-reject-arg a 'integerp))
1325 (if w (setq a (math-clip a w)))
1326 (if (math-messy-integerp a) (setq a (math-trunc a)))
1327 (let* ((calc-number-radix 2)
1328 (neg (math-negp a))
1329 (aa (if neg (math-sub -1 a) a))
1330 (str (if (eq aa 0)
1331 ""
1332 (if (consp aa)
1333 (math-format-bignum-binary (cdr aa))
1334 (math-format-binary aa))))
1335 (zero (if neg ?1 ?0))
1336 (one (if neg ?0 ?1))
1337 (len (length str))
1338 (vec (list 'vec))
1339 (pos (1- len)) pos2)
1340 (while (>= pos 0)
1341 (if (eq (aref str pos) zero)
1342 (setq pos (1- pos))
1343 (setq pos2 pos)
1344 (while (and (>= pos 0) (eq (aref str pos) one))
1345 (setq pos (1- pos)))
1346 (setq vec (cons (if (= pos (1- pos2))
1347 (- len pos2 1)
1348 (list 'intv 3 (- len pos2 1) (- len pos 2)))
1349 vec))))
1350 (if neg
1351 (setq vec (cons (list 'intv 2 len '(var inf var-inf)) vec)))
bf77c646 1352 (math-clean-set (nreverse vec))))
136211a9
EZ
1353
1354(defun calcFunc-rdup (a)
1355 (if (math-simple-set a)
1356 (progn
1357 (and (Math-objectp a) (setq a (list 'vec a)))
1358 (or (math-vectorp a) (math-reject-arg a 'vectorp))
1359 (setq a (sort (copy-sequence (cdr a)) 'math-beforep))
1360 (let ((p a))
1361 (while (cdr p)
1362 (if (Math-equal (car p) (nth 1 p))
1363 (setcdr p (cdr (cdr p)))
1364 (setq p (cdr p)))))
1365 (cons 'vec a))
bf77c646 1366 (math-clean-set (math-prepare-set a))))
136211a9
EZ
1367
1368(defun math-prepare-set (a)
1369 (if (Math-objectp a)
1370 (setq a (list 'vec a))
1371 (or (math-vectorp a) (math-reject-arg a 'vectorp))
1372 (setq a (cons 'vec (sort (copy-sequence (cdr a)) 'math-beforep))))
1373 (let ((p a) res)
1374
1375 ;; Convert all elements to non-empty intervals.
1376 (while (cdr p)
1377 (if (eq (car-safe (nth 1 p)) 'intv)
1378 (if (math-intv-constp (nth 1 p))
1379 (if (and (memq (nth 1 (nth 1 p)) '(0 1 2))
1380 (Math-equal (nth 2 (nth 1 p)) (nth 3 (nth 1 p))))
1381 (setcdr p (cdr (cdr p)))
1382 (setq p (cdr p)))
1383 (math-reject-arg (nth 1 p) 'constp))
1384 (or (Math-anglep (nth 1 p))
1385 (eq (car (nth 1 p)) 'date)
1386 (equal (nth 1 p) '(var inf var-inf))
1387 (equal (nth 1 p) '(neg (var inf var-inf)))
1388 (math-reject-arg (nth 1 p) 'realp))
1389 (setcar (cdr p) (list 'intv 3 (nth 1 p) (nth 1 p)))
1390 (setq p (cdr p))))
1391
1392 ;; Combine redundant intervals.
1393 (setq p a)
1394 (while (cdr (cdr p))
1395 (if (or (memq (setq res (math-compare (nth 3 (nth 1 p))
1396 (nth 2 (nth 2 p))))
1397 '(-1 2))
1398 (and (eq res 0)
1399 (memq (nth 1 (nth 1 p)) '(0 2))
1400 (memq (nth 1 (nth 2 p)) '(0 1))))
1401 (setq p (cdr p))
1402 (setq res (math-compare (nth 3 (nth 1 p)) (nth 3 (nth 2 p))))
1403 (setcdr p (cons (list 'intv
1404 (+ (logand (logior (nth 1 (nth 1 p))
1405 (if (Math-equal
1406 (nth 2 (nth 1 p))
1407 (nth 2 (nth 2 p)))
1408 (nth 1 (nth 2 p))
1409 0))
1410 2)
1411 (logand (logior (if (memq res '(1 0 2))
1412 (nth 1 (nth 1 p)) 0)
1413 (if (memq res '(-1 0 2))
1414 (nth 1 (nth 2 p)) 0))
1415 1))
1416 (nth 2 (nth 1 p))
1417 (if (eq res 1)
1418 (nth 3 (nth 1 p))
1419 (nth 3 (nth 2 p))))
1420 (cdr (cdr (cdr p))))))))
bf77c646 1421 a)
136211a9
EZ
1422
1423(defun math-clean-set (a &optional always-vec)
1424 (let ((p a) res)
1425 (while (cdr p)
1426 (if (and (eq (car-safe (nth 1 p)) 'intv)
1427 (Math-equal (nth 2 (nth 1 p)) (nth 3 (nth 1 p))))
1428 (setcar (cdr p) (nth 2 (nth 1 p))))
1429 (setq p (cdr p)))
1430 (if (and (not (cdr (cdr a)))
1431 (eq (car-safe (nth 1 a)) 'intv)
1432 (not always-vec))
1433 (nth 1 a)
bf77c646 1434 a)))
136211a9
EZ
1435
1436(defun math-simple-set (a)
1437 (or (and (Math-objectp a)
1438 (not (eq (car-safe a) 'intv)))
1439 (and (Math-vectorp a)
1440 (progn
1441 (while (and (setq a (cdr a))
1442 (not (eq (car-safe (car a)) 'intv))))
bf77c646 1443 (null a)))))
136211a9
EZ
1444
1445
1446
1447
1448;;; Compute a right-handed vector cross product. [O O O] [Public]
1449(defun calcFunc-cross (a b)
1450 (if (and (eq (car-safe a) 'vec)
1451 (= (length a) 4))
1452 (if (and (eq (car-safe b) 'vec)
1453 (= (length b) 4))
1454 (list 'vec
1455 (math-sub (math-mul (nth 2 a) (nth 3 b))
1456 (math-mul (nth 3 a) (nth 2 b)))
1457 (math-sub (math-mul (nth 3 a) (nth 1 b))
1458 (math-mul (nth 1 a) (nth 3 b)))
1459 (math-sub (math-mul (nth 1 a) (nth 2 b))
1460 (math-mul (nth 2 a) (nth 1 b))))
1461 (math-reject-arg b "*Three-vector expected"))
bf77c646 1462 (math-reject-arg a "*Three-vector expected")))
136211a9
EZ
1463
1464
1465
866ebaa9
JB
1466;; The variable math-rb-close is local to math-read-brackets, but
1467;; is used by math-read-vector, which is called (directly and
1468;; indirectly) by math-read-brackets.
1469(defvar math-rb-close)
136211a9 1470
388df0be
JB
1471;; The next few variables are local to math-read-exprs in calc-aent.el
1472;; and math-read-expr in calc-ext.el, but are set in functions they call.
1473(defvar math-exp-pos)
1474(defvar math-exp-str)
1475(defvar math-exp-old-pos)
1476(defvar math-exp-token)
1477(defvar math-exp-keep-spaces)
1478(defvar math-expr-data)
1479
866ebaa9 1480(defun math-read-brackets (space-sep math-rb-close)
136211a9
EZ
1481 (and space-sep (setq space-sep (not (math-check-for-commas))))
1482 (math-read-token)
411b1407 1483 (while (eq math-exp-token 'space)
136211a9 1484 (math-read-token))
866ebaa9 1485 (if (or (equal math-expr-data math-rb-close)
411b1407 1486 (eq math-exp-token 'end))
136211a9
EZ
1487 (progn
1488 (math-read-token)
1489 '(vec))
411b1407
JB
1490 (let ((save-exp-pos math-exp-pos)
1491 (save-exp-old-pos math-exp-old-pos)
1492 (save-exp-token math-exp-token)
5c8a5f96 1493 (save-exp-data math-expr-data)
411b1407 1494 (vals (let ((math-exp-keep-spaces space-sep))
5c8a5f96
JB
1495 (if (or (equal math-expr-data "\\dots")
1496 (equal math-expr-data "\\ldots"))
136211a9
EZ
1497 '(vec (neg (var inf var-inf)))
1498 (catch 'syntax (math-read-vector))))))
1499 (if (stringp vals)
1500 (if space-sep
411b1407
JB
1501 (let ((error-exp-pos math-exp-pos)
1502 (error-exp-old-pos math-exp-old-pos)
136211a9 1503 vals2)
411b1407
JB
1504 (setq math-exp-pos save-exp-pos
1505 math-exp-old-pos save-exp-old-pos
1506 math-exp-token save-exp-token
5c8a5f96 1507 math-expr-data save-exp-data)
411b1407 1508 (let ((math-exp-keep-spaces nil))
136211a9
EZ
1509 (setq vals2 (catch 'syntax (math-read-vector))))
1510 (if (and (not (stringp vals2))
5c8a5f96 1511 (or (assoc math-expr-data '(("\\ldots") ("\\dots") (";")))
866ebaa9 1512 (equal math-expr-data math-rb-close)
411b1407 1513 (eq math-exp-token 'end)))
136211a9
EZ
1514 (setq space-sep nil
1515 vals vals2)
411b1407
JB
1516 (setq math-exp-pos error-exp-pos
1517 math-exp-old-pos error-exp-old-pos)
136211a9
EZ
1518 (throw 'syntax vals)))
1519 (throw 'syntax vals)))
5c8a5f96
JB
1520 (if (or (equal math-expr-data "\\dots")
1521 (equal math-expr-data "\\ldots"))
136211a9
EZ
1522 (progn
1523 (math-read-token)
1524 (setq vals (if (> (length vals) 2)
1525 (cons 'calcFunc-mul (cdr vals)) (nth 1 vals)))
866ebaa9 1526 (let ((exp2 (if (or (equal math-expr-data math-rb-close)
5c8a5f96 1527 (equal math-expr-data ")")
411b1407 1528 (eq math-exp-token 'end))
136211a9
EZ
1529 '(var inf var-inf)
1530 (math-read-expr-level 0))))
1531 (setq vals
1532 (list 'intv
5c8a5f96 1533 (if (equal math-expr-data ")") 2 3)
136211a9
EZ
1534 vals
1535 exp2)))
866ebaa9 1536 (if (not (or (equal math-expr-data math-rb-close)
5c8a5f96 1537 (equal math-expr-data ")")
411b1407 1538 (eq math-exp-token 'end)))
136211a9 1539 (throw 'syntax "Expected `]'")))
5c8a5f96 1540 (if (equal math-expr-data ";")
411b1407 1541 (let ((math-exp-keep-spaces space-sep))
136211a9 1542 (setq vals (cons 'vec (math-read-matrix (list vals))))))
866ebaa9 1543 (if (not (or (equal math-expr-data math-rb-close)
411b1407 1544 (eq math-exp-token 'end)))
136211a9 1545 (throw 'syntax "Expected `]'")))
411b1407 1546 (or (eq math-exp-token 'end)
136211a9 1547 (math-read-token))
bf77c646 1548 vals)))
136211a9
EZ
1549
1550(defun math-check-for-commas (&optional balancing)
1551 (let ((count 0)
411b1407 1552 (pos (1- math-exp-pos)))
136211a9
EZ
1553 (while (and (>= count 0)
1554 (setq pos (string-match
1555 (if balancing "[],[{}()<>]" "[],[{}()]")
411b1407
JB
1556 math-exp-str (1+ pos)))
1557 (or (/= (aref math-exp-str pos) ?,) (> count 0) balancing))
1558 (cond ((memq (aref math-exp-str pos) '(?\[ ?\{ ?\( ?\<))
136211a9 1559 (setq count (1+ count)))
411b1407 1560 ((memq (aref math-exp-str pos) '(?\] ?\} ?\) ?\>))
136211a9
EZ
1561 (setq count (1- count)))))
1562 (if balancing
1563 pos
411b1407 1564 (and pos (= (aref math-exp-str pos) ?,)))))
136211a9
EZ
1565
1566(defun math-read-vector ()
1567 (let* ((val (list (math-read-expr-level 0)))
1568 (last val))
1569 (while (progn
411b1407 1570 (while (eq math-exp-token 'space)
136211a9 1571 (math-read-token))
411b1407 1572 (and (not (eq math-exp-token 'end))
5c8a5f96 1573 (not (equal math-expr-data ";"))
866ebaa9 1574 (not (equal math-expr-data math-rb-close))
5c8a5f96
JB
1575 (not (equal math-expr-data "\\dots"))
1576 (not (equal math-expr-data "\\ldots"))))
1577 (if (equal math-expr-data ",")
136211a9 1578 (math-read-token))
411b1407 1579 (while (eq math-exp-token 'space)
136211a9
EZ
1580 (math-read-token))
1581 (let ((rest (list (math-read-expr-level 0))))
1582 (setcdr last rest)
1583 (setq last rest)))
bf77c646 1584 (cons 'vec val)))
136211a9
EZ
1585
1586(defun math-read-matrix (mat)
5c8a5f96 1587 (while (equal math-expr-data ";")
136211a9 1588 (math-read-token)
411b1407 1589 (while (eq math-exp-token 'space)
136211a9
EZ
1590 (math-read-token))
1591 (setq mat (nconc mat (list (math-read-vector)))))
bf77c646 1592 mat)
136211a9 1593
429dae43
JB
1594(provide 'calc-vec)
1595
ab5796a9 1596;;; arch-tag: 7902a7af-ec69-440a-8635-ebb4db263402
bf77c646 1597;;; calc-vec.el ends here