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