Port various comments from new VC to reduce the noise in the diff.
[emacs.git] / lisp / calc / calc-vec.el
blobe4b3e1e5bbc0ee5a969f01d7dedb26483a277e13
1 ;;; calc-vec.el --- vector functions for Calc
3 ;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004,
4 ;; 2005, 2006, 2007 Free Software Foundation, Inc.
6 ;; Author: David Gillespie <daveg@synaptics.com>
7 ;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
9 ;; This file is part of GNU Emacs.
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 3, or (at your option)
14 ;; any later version.
16 ;; GNU Emacs is distributed in the hope that it will be useful,
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.
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.
26 ;;; Commentary:
28 ;;; Code:
30 ;; This file is autoloaded from calc-ext.el.
32 (require 'calc-ext)
33 (require 'calc-macs)
35 (defun calc-display-strings (n)
36 (interactive "P")
37 (calc-wrapper
38 (message (if (calc-change-mode 'calc-display-strings n t t)
39 "Displaying vectors of integers as quoted strings"
40 "Displaying vectors of integers normally"))))
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)))
53 (calc-enter-result (+ nn num -1) "pack" (calc-pack-items mode items)))))
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))))
67 2))))
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
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)))))
208 (error "Invalid packing mode: %d" mode))))
210 (defvar calc-unpack-with-type nil)
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))
218 (calc-top))))))
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))
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) )))
230 (error "Argument must be a composite object")))))
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")))
334 (error "Invalid unpacking mode: %d" mode))))
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))
342 (list 'calcFunc-diag (calc-top-n 1))))))
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
350 (prefix-numeric-value n))))))
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
358 (prefix-numeric-value n))))))
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)
365 (prefix-numeric-value n)))))
367 (defun calc-cons (arg)
368 (interactive "P")
369 (calc-wrapper
370 (if (calc-is-hyperbolic)
371 (calc-binary-op "rcns" 'calcFunc-rcons arg)
372 (calc-binary-op "cons" 'calcFunc-cons arg))))
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)
384 (calc-unary-op "head" 'calcFunc-head arg)))))
386 (defun calc-tail (arg)
387 (interactive "P")
388 (calc-invert-func)
389 (calc-head arg))
391 (defun calc-vlength (arg)
392 (interactive "P")
393 (calc-wrapper
394 (if (calc-is-hyperbolic)
395 (calc-unary-op "dims" 'calcFunc-mdims arg)
396 (calc-unary-op "len" 'calcFunc-vlen arg))))
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)
402 (prefix-numeric-value n)))))
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"
410 (if arg (append func (list (prefix-numeric-value arg))) func)))))
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)))
418 (calc-enter-result 3 "svec" (cons 'calcFunc-subvec (calc-top-list-n 3))))))
420 (defun calc-reverse-vector (arg)
421 (interactive "P")
422 (calc-wrapper
423 (calc-unary-op "rev" 'calcFunc-rev arg)))
425 (defun calc-mask-vector (arg)
426 (interactive "P")
427 (calc-wrapper
428 (calc-binary-op "vmsk" 'calcFunc-vmask arg)))
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)))
435 (calc-binary-op "vexp" 'calcFunc-vexp arg))))
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)))
442 (calc-enter-result 1 "sort" (list 'calcFunc-sort (calc-top-n 1))))))
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)))
449 (calc-enter-result 1 "grad" (list 'calcFunc-grade (calc-top-n 1))))))
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)
461 (prefix-numeric-value n))))))
463 (defun calc-transpose (arg)
464 (interactive "P")
465 (calc-wrapper
466 (calc-unary-op "trn" 'calcFunc-trn arg)))
468 (defun calc-conj-transpose (arg)
469 (interactive "P")
470 (calc-wrapper
471 (calc-unary-op "ctrn" 'calcFunc-ctrn arg)))
473 (defun calc-cross (arg)
474 (interactive "P")
475 (calc-wrapper
476 (calc-binary-op "cros" 'calcFunc-cross arg)))
478 (defun calc-remove-duplicates (arg)
479 (interactive "P")
480 (calc-wrapper
481 (calc-unary-op "rdup" 'calcFunc-rdup arg)))
483 (defun calc-set-union (arg)
484 (interactive "P")
485 (calc-wrapper
486 (calc-binary-op "unio" 'calcFunc-vunion arg '(vec) 'calcFunc-rdup)))
488 (defun calc-set-intersect (arg)
489 (interactive "P")
490 (calc-wrapper
491 (calc-binary-op "intr" 'calcFunc-vint arg '(vec) 'calcFunc-rdup)))
493 (defun calc-set-difference (arg)
494 (interactive "P")
495 (calc-wrapper
496 (calc-binary-op "diff" 'calcFunc-vdiff arg '(vec) 'calcFunc-rdup)))
498 (defun calc-set-xor (arg)
499 (interactive "P")
500 (calc-wrapper
501 (calc-binary-op "xor" 'calcFunc-vxor arg '(vec) 'calcFunc-rdup)))
503 (defun calc-set-complement (arg)
504 (interactive "P")
505 (calc-wrapper
506 (calc-unary-op "cmpl" 'calcFunc-vcompl arg)))
508 (defun calc-set-floor (arg)
509 (interactive "P")
510 (calc-wrapper
511 (calc-unary-op "vflr" 'calcFunc-vfloor arg)))
513 (defun calc-set-enumerate (arg)
514 (interactive "P")
515 (calc-wrapper
516 (calc-unary-op "enum" 'calcFunc-venum arg)))
518 (defun calc-set-span (arg)
519 (interactive "P")
520 (calc-wrapper
521 (calc-unary-op "span" 'calcFunc-vspan arg)))
523 (defun calc-set-cardinality (arg)
524 (interactive "P")
525 (calc-wrapper
526 (calc-unary-op "card" 'calcFunc-vcard arg)))
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)
533 (calc-unary-op "bupk" 'calcFunc-vunpack arg))))
535 (defun calc-pack-bits (arg)
536 (interactive "P")
537 (calc-invert-func)
538 (calc-unpack-bits arg))
541 (defun calc-rnorm (arg)
542 (interactive "P")
543 (calc-wrapper
544 (calc-unary-op "rnrm" 'calcFunc-rnorm arg)))
546 (defun calc-cnorm (arg)
547 (interactive "P")
548 (calc-wrapper
549 (calc-unary-op "cnrm" 'calcFunc-cnorm arg)))
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
563 (calc-top-n 1) n)))))))
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
577 (calc-top-n 1) n)))))))
580 ;;;; Vectors.
582 (defun calcFunc-mdims (m)
583 (or (math-vectorp m)
584 (math-reject-arg m 'vectorp))
585 (cons 'vec (math-mat-dimens m)))
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)))
592 (funcall f a)))
594 (defun math-dimension-error ()
595 (calc-record-why "*Dimension error")
596 (signal 'wrong-type-argument nil))
599 ;;; Build a vector out of a list of objects. [Public]
600 (defun calcFunc-vec (&rest objs)
601 (cons 'vec objs))
604 ;;; Build a constant vector or matrix. [Public]
605 (defun calcFunc-cvec (obj &rest dims)
606 (math-make-vec-dimen obj dims))
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))
618 obj))
620 (defun calcFunc-head (vec)
621 (if (and (Math-vectorp vec)
622 (cdr vec))
623 (nth 1 vec)
624 (calc-record-why 'vectorp vec)
625 (list 'calcFunc-head vec)))
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)
632 (list 'calcFunc-tail vec)))
634 (defun calcFunc-cons (head tail)
635 (if (Math-vectorp tail)
636 (cons 'vec (cons head (cdr tail)))
637 (calc-record-why 'vectorp tail)
638 (list 'calcFunc-cons head tail)))
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)
647 (list 'calcFunc-rhead vec)))
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)
654 (list 'calcFunc-rtail vec)))
656 (defun calcFunc-rcons (head tail)
657 (if (Math-vectorp head)
658 (append head (list tail))
659 (calc-record-why 'vectorp head)
660 (list 'calcFunc-rcons head tail)))
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)))
684 (funcall f a b))))
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)
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))))
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))
708 (math-reduce-cols-col-step f a (1+ col) cols))))
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)))
715 (cdr a))
716 tot))
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)
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)
735 (list 'calcFunc-vlen v))))
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)
751 (math-reject-arg n "*Index out of range")))))
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))
759 mat))
761 ;;; Get the Nth column of a matrix.
762 (defun math-mat-col (mat n)
763 (cons 'vec (mapcar (function (lambda (x) (elt x n))) (cdr mat))))
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))
782 (math-reject-arg n "*Index out of range")))))
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)
789 (math-mat-less-row (cdr mat) (1- n)))))
791 (defun calcFunc-mrrow (mat n) ; [Public]
792 (and (integerp (setq n (math-check-integer n)))
793 (> n 0)
794 (< n (length mat))
795 (math-mat-less-row mat n)))
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)))
800 (cdr mat))))
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))
808 (math-mat-less-row mat n))))
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)
814 (list 'calcFunc-getdiag mat)))
816 (defun math-get-diag-step (row n)
817 (and row
818 (cons (nth n (car row))
819 (math-get-diag-step (cdr row) (1+ n)))))
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)))
826 (cons 'vec m)))
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)
835 (math-reject-arg mat 'matrixp))))
837 (defun calcFunc-ctrn (mat)
838 (calcFunc-conj (calcFunc-trn mat)))
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"))
849 (error (math-reject-arg els (nth 1 err)))))
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))
855 (error (math-reject-arg thing (nth 1 err)))))
857 (defun calcFunc-unpackt (mode thing)
858 (let ((calc-unpack-with-type 'pair))
859 (calcFunc-unpack mode thing)))
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)))))
876 mat))))
878 (defun math-flatten-vector (vec) ; [L V]
879 (if (math-vectorp vec)
880 (apply 'append (mapcar 'math-flatten-vector (cdr vec)))
881 (list vec)))
883 (defun calcFunc-vconcat (a b)
884 (math-normalize (list '| a b)))
886 (defun calcFunc-vconcatrev (a b)
887 (math-normalize (list '| b a)))
889 (defun calcFunc-append (v1 v2)
890 (if (and (math-vectorp v1) (math-vectorp v2))
891 (append v1 (cdr v2))
892 (list 'calcFunc-append v1 v2)))
894 (defun calcFunc-appendrev (v1 v2)
895 (calcFunc-append v2 v1))
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)))
902 (copy-sequence m)))
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)
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))
918 (list 'calcFunc-diag a))))
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)
927 (list 'calcFunc-idn a))))
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))
940 (calcFunc-idn a))))
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))
949 nil))
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))))))
976 (cons 'vec vec))))
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)))
987 (if vec n 0)))
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)))
1006 (cons 'vec vec))))
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))
1021 (let ((tail (nthcdr end vec))
1022 (chop (nthcdr (1- start) (setq vec (copy-sequence vec)))))
1023 (setcdr chop nil)
1024 (append vec tail)))))
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)))
1030 (math-reject-arg vec 'vectorp)))
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))))
1046 (cons 'vec (nreverse new)))))
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))))
1063 (cons 'vec (nreverse new))))
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)
1074 (list 'calcFunc-rnorm a)))
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)
1084 (list 'calcFunc-cnorm a)))
1086 (defun math-add-abs (a b)
1087 (math-add (math-abs a) (math-abs b)))
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))
1094 (math-reject-arg vec 'vectorp)))
1096 (defun calcFunc-rsort (vec) ; [Public]
1097 (if (math-vectorp vec)
1098 (cons 'vec (nreverse (sort (copy-sequence (cdr vec)) 'math-beforep)))
1099 (math-reject-arg vec 'vectorp)))
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)
1106 (defun calcFunc-grade (math-grade-vec)
1107 (if (math-vectorp math-grade-vec)
1108 (let* ((len (1- (length math-grade-vec))))
1109 (cons 'vec (sort (cdr (calcFunc-index len)) 'math-grade-beforep)))
1110 (math-reject-arg math-grade-vec 'vectorp)))
1112 (defun calcFunc-rgrade (math-grade-vec)
1113 (if (math-vectorp math-grade-vec)
1114 (let* ((len (1- (length math-grade-vec))))
1115 (cons 'vec (nreverse (sort (cdr (calcFunc-index len))
1116 'math-grade-beforep))))
1117 (math-reject-arg math-grade-vec 'vectorp)))
1119 (defun math-grade-beforep (i j)
1120 (math-beforep (nth i math-grade-vec) (nth j math-grade-vec)))
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)))))
1146 (cons 'vec (append res nil))))
1149 ;;; Set operations.
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)))
1159 (calcFunc-rdup (append a b)))
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)
1176 (calcFunc-vcompl b)))))
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)))
1193 (calcFunc-vcompl (calcFunc-vunion (calcFunc-vcompl a) b))))
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))
1215 (calcFunc-vcompl (calcFunc-vunion a cb))))))
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)))
1238 (math-clean-set (nreverse vec))))
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)))
1248 '(intv 2 0 0)))
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))
1274 (math-clean-set vec always-vec)))
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)))
1285 count))
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)))
1298 (nth 2 (nth 1 p))))
1299 (cdr (cdr p)))))
1300 (setq p next))
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))))))
1321 accum))
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)
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)))
1352 (math-clean-set (nreverse vec))))
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))
1366 (math-clean-set (math-prepare-set a))))
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)
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))))
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))
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))
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))))))))
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)
1434 a)))
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))))
1443 (null a)))))
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"))
1462 (math-reject-arg a "*Three-vector expected")))
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)
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)
1480 (defun math-read-brackets (space-sep math-rb-close)
1481 (and space-sep (setq space-sep (not (math-check-for-commas))))
1482 (math-read-token)
1483 (while (eq math-exp-token 'space)
1484 (math-read-token))
1485 (if (or (equal math-expr-data math-rb-close)
1486 (eq math-exp-token 'end))
1487 (progn
1488 (math-read-token)
1489 '(vec))
1490 (let ((save-exp-pos math-exp-pos)
1491 (save-exp-old-pos math-exp-old-pos)
1492 (save-exp-token math-exp-token)
1493 (save-exp-data math-expr-data)
1494 (vals (let ((math-exp-keep-spaces space-sep))
1495 (if (or (equal math-expr-data "\\dots")
1496 (equal math-expr-data "\\ldots"))
1497 '(vec (neg (var inf var-inf)))
1498 (catch 'syntax (math-read-vector))))))
1499 (if (stringp vals)
1500 (if space-sep
1501 (let ((error-exp-pos math-exp-pos)
1502 (error-exp-old-pos math-exp-old-pos)
1503 vals2)
1504 (setq math-exp-pos save-exp-pos
1505 math-exp-old-pos save-exp-old-pos
1506 math-exp-token save-exp-token
1507 math-expr-data save-exp-data)
1508 (let ((math-exp-keep-spaces nil))
1509 (setq vals2 (catch 'syntax (math-read-vector))))
1510 (if (and (not (stringp vals2))
1511 (or (assoc math-expr-data '(("\\ldots") ("\\dots") (";")))
1512 (equal math-expr-data math-rb-close)
1513 (eq math-exp-token 'end)))
1514 (setq space-sep nil
1515 vals vals2)
1516 (setq math-exp-pos error-exp-pos
1517 math-exp-old-pos error-exp-old-pos)
1518 (throw 'syntax vals)))
1519 (throw 'syntax vals)))
1520 (if (or (equal math-expr-data "\\dots")
1521 (equal math-expr-data "\\ldots"))
1522 (progn
1523 (math-read-token)
1524 (setq vals (if (> (length vals) 2)
1525 (cons 'calcFunc-mul (cdr vals)) (nth 1 vals)))
1526 (let ((exp2 (if (or (equal math-expr-data math-rb-close)
1527 (equal math-expr-data ")")
1528 (eq math-exp-token 'end))
1529 '(var inf var-inf)
1530 (math-read-expr-level 0))))
1531 (setq vals
1532 (list 'intv
1533 (if (equal math-expr-data ")") 2 3)
1534 vals
1535 exp2)))
1536 (if (not (or (equal math-expr-data math-rb-close)
1537 (equal math-expr-data ")")
1538 (eq math-exp-token 'end)))
1539 (throw 'syntax "Expected `]'")))
1540 (if (equal math-expr-data ";")
1541 (let ((math-exp-keep-spaces space-sep))
1542 (setq vals (cons 'vec (math-read-matrix (list vals))))))
1543 (if (not (or (equal math-expr-data math-rb-close)
1544 (eq math-exp-token 'end)))
1545 (throw 'syntax "Expected `]'")))
1546 (or (eq math-exp-token 'end)
1547 (math-read-token))
1548 vals)))
1550 (defun math-check-for-commas (&optional balancing)
1551 (let ((count 0)
1552 (pos (1- math-exp-pos)))
1553 (while (and (>= count 0)
1554 (setq pos (string-match
1555 (if balancing "[],[{}()<>]" "[],[{}()]")
1556 math-exp-str (1+ pos)))
1557 (or (/= (aref math-exp-str pos) ?,) (> count 0) balancing))
1558 (cond ((memq (aref math-exp-str pos) '(?\[ ?\{ ?\( ?\<))
1559 (setq count (1+ count)))
1560 ((memq (aref math-exp-str pos) '(?\] ?\} ?\) ?\>))
1561 (setq count (1- count)))))
1562 (if balancing
1564 (and pos (= (aref math-exp-str pos) ?,)))))
1566 (defun math-read-vector ()
1567 (let* ((val (list (math-read-expr-level 0)))
1568 (last val))
1569 (while (progn
1570 (while (eq math-exp-token 'space)
1571 (math-read-token))
1572 (and (not (eq math-exp-token 'end))
1573 (not (equal math-expr-data ";"))
1574 (not (equal math-expr-data math-rb-close))
1575 (not (equal math-expr-data "\\dots"))
1576 (not (equal math-expr-data "\\ldots"))))
1577 (if (equal math-expr-data ",")
1578 (math-read-token))
1579 (while (eq math-exp-token 'space)
1580 (math-read-token))
1581 (let ((rest (list (math-read-expr-level 0))))
1582 (setcdr last rest)
1583 (setq last rest)))
1584 (cons 'vec val)))
1586 (defun math-read-matrix (mat)
1587 (while (equal math-expr-data ";")
1588 (math-read-token)
1589 (while (eq math-exp-token 'space)
1590 (math-read-token))
1591 (setq mat (nconc mat (list (math-read-vector)))))
1592 mat)
1594 (provide 'calc-vec)
1596 ;;; arch-tag: 7902a7af-ec69-440a-8635-ebb4db263402
1597 ;;; calc-vec.el ends here