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