1 ;;; calc-vec.el --- vector functions for Calc
3 ;; Copyright (C) 1990-1993, 2001-2015 Free Software Foundation, Inc.
5 ;; Author: David Gillespie <daveg@synaptics.com>
6 ;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
27 ;; This file is autoloaded from calc-ext.el.
32 ;; Declare functions which are defined elsewhere.
33 (declare-function math-read-expr-level
"calc-aent" (exp-prec &optional exp-term
))
36 (defun calc-display-strings (n)
39 (message (if (calc-change-mode 'calc-display-strings n t t
)
40 "Displaying vectors of integers as quoted strings"
41 "Displaying vectors of integers normally"))))
47 (let* ((nn (if n
1 2))
48 (mode (if n
(prefix-numeric-value n
) (calc-top-n 1)))
49 (mode (if (and (Math-vectorp mode
) (cdr mode
)) (cdr mode
)
50 (if (integerp mode
) mode
51 (error "Packing mode must be an integer or vector of integers"))))
52 (num (calc-pack-size mode
))
53 (items (calc-top-list num nn
)))
54 (calc-enter-result (+ nn num -
1) "pack" (calc-pack-items mode items
)))))
56 (defun calc-pack-size (mode)
60 (or (integerp (car mode
)) (error "Vector of integers expected"))
61 (setq size
(* size
(calc-pack-size (car mode
)))
64 (error "Zero dimensions not allowed")
67 (t (or (cdr (assq mode
'((-3 .
3) (-13 .
1) (-14 .
3) (-15 .
6))))
70 (defun calc-pack-items (mode items
)
73 (let* ((size (calc-pack-size (cdr mode
)))
78 (setq p
(nthcdr (1- size
) items
)
83 (setq new
(cons (calc-pack-items (cdr mode
) row
) new
)))
84 (calc-pack-items (car mode
) (nreverse new
)))
85 (calc-pack-items (car mode
) items
)))
89 (if (and (math-objvecp (car items
))
90 (math-objvecp (nth 1 items
))
91 (math-objvecp (nth 2 items
)))
92 (if (and (math-num-integerp (car items
))
93 (math-num-integerp (nth 1 items
)))
94 (if (math-realp (nth 2 items
))
96 (error "Seconds must be real"))
97 (error "Hours and minutes must be integers"))
98 (math-normalize (list '+
100 (if (eq calc-angle-mode
'rad
)
104 (list '* (nth 1 items
) '(hms 0 1 0)))
105 (list '* (nth 2 items
) '(hms 0 0 1))))))
107 (if (math-realp (car items
))
109 (if (eq (car-safe (car items
)) 'date
)
111 (if (math-objvecp (car items
))
112 (error "Date value must be real")
113 (cons 'calcFunc-date items
)))))
114 ((memq mode
'(-14 -
15))
116 (while (and p
(math-objvecp (car p
)))
117 (or (math-integerp (car p
))
118 (error "Components must be integers"))
121 (cons 'calcFunc-date items
)
122 (list 'date
(math-dt-to-date items
)))))
123 ((or (eq (car-safe (car items
)) 'vec
)
124 (eq (car-safe (nth 1 items
)) 'vec
))
125 (let* ((x (car items
))
126 (vx (eq (car-safe x
) 'vec
))
128 (vy (eq (car-safe y
) 'vec
))
130 (n (1- (length (if vx x y
)))))
132 (/= n
(1- (length y
)))
133 (error "Vectors must be the same length"))
134 (while (>= (setq n
(1- n
)) 0)
135 (setq z
(cons (calc-pack-items
137 (list (if vx
(car (setq x
(cdr x
))) x
)
138 (if vy
(car (setq y
(cdr y
))) y
)))
140 (cons 'vec
(nreverse z
))))
142 (if (and (math-realp (car items
)) (math-realp (nth 1 items
)))
144 (if (and (math-objectp (car items
)) (math-objectp (nth 1 items
)))
145 (error "Components must be real"))
146 (math-normalize (list '+ (car items
)
147 (list '* (nth 1 items
) '(cplx 0 1))))))
149 (if (and (math-realp (car items
)) (math-anglep (nth 1 items
)))
151 (if (and (math-objectp (car items
)) (math-objectp (nth 1 items
)))
152 (error "Components must be real"))
153 (math-normalize (list '* (car items
)
154 (if (math-anglep (nth 1 items
))
155 (list 'polar
1 (nth 1 items
))
165 (let ((x (car items
))
166 (sigma (nth 1 items
)))
167 (if (or (math-scalarp x
) (not (math-objvecp x
)))
168 (if (or (math-anglep sigma
) (not (math-objvecp sigma
)))
169 (math-make-sdev x sigma
)
170 (error "Error component must be real"))
171 (error "Mean component must be real or complex"))))
173 (let ((a (car items
))
175 (if (and (math-anglep a
) (math-anglep m
))
178 (error "Modulus must be positive"))
179 (if (and (math-objectp a
) (math-objectp m
))
180 (error "Components must be real"))
181 (list 'calcFunc-makemod a m
))))
182 ((memq mode
'(-6 -
7 -
8 -
9))
183 (let ((lo (car items
))
185 (if (and (or (math-anglep lo
) (eq (car lo
) 'date
)
186 (not (math-objvecp lo
)))
187 (or (math-anglep hi
) (eq (car hi
) 'date
)
188 (not (math-objvecp hi
))))
189 (math-make-intv (+ mode
9) lo hi
)
190 (error "Components must be real"))))
192 (if (math-zerop (nth 1 items
))
193 (error "Denominator must not be zero")
194 (if (and (math-integerp (car items
)) (math-integerp (nth 1 items
)))
195 (math-normalize (cons 'frac items
))
196 (if (and (math-objectp (car items
)) (math-objectp (nth 1 items
)))
197 (error "Components must be integers"))
198 (cons 'calcFunc-fdiv items
))))
199 ((memq mode
'(-11 -
12))
200 (if (and (math-realp (car items
)) (math-integerp (nth 1 items
)))
201 (calcFunc-scf (math-float (car items
)) (nth 1 items
))
202 (if (and (math-objectp (car items
)) (math-objectp (nth 1 items
)))
203 (error "Components must be integers"))
206 (list 'calcFunc-float
(car items
))
209 (error "Invalid packing mode: %d" mode
))))
211 (defvar calc-unpack-with-type nil
)
212 (defun calc-unpack (mode)
215 (let ((calc-unpack-with-type t
))
216 (calc-pop-push-record-list 1 "unpk" (calc-unpack-item
218 (prefix-numeric-value mode
))
221 (defun calc-unpack-type (item)
222 (cond ((eq (car-safe item
) 'vec
)
224 ((eq (car-safe item
) 'intv
)
227 (or (cdr (assq (car-safe item
) '( (cplx . -
1) (polar . -
2)
228 (hms . -
3) (sdev . -
4) (mod . -
5)
229 (frac . -
10) (float . -
11)
231 (error "Argument must be a composite object")))))
233 (defun calc-unpack-item (mode item
)
235 (if (or (and (not (memq (car-safe item
) '(frac float cplx polar vec
239 (eq (car-safe item
) 'var
))
240 (error "Argument must be a composite object or function call"))
241 (if (eq (car item
) 'intv
)
247 (setq item
(list item
))
249 (setq type
(calc-unpack-type (car item
))
250 dims
(cons type dims
)
251 new
(calc-unpack-item nil
(car item
)))
252 (while (setq item
(cdr item
))
253 (or (= (calc-unpack-type (car item
)) type
)
254 (error "Inconsistent types or dimensions in vector elements"))
255 (setq new
(append new
(calc-unpack-item nil
(car item
)))))
258 (if (cdr dims
) (setq dims
(list (cons 'vec
(nreverse dims
)))))
259 (cond ((eq calc-unpack-with-type
'pair
)
260 (list (car dims
) (cons 'vec item
)))
261 (calc-unpack-with-type
264 ((eq calc-unpack-with-type
'pair
)
265 (let ((calc-unpack-with-type nil
))
266 (list mode
(cons 'vec
(calc-unpack-item mode item
)))))
268 (if (eq (car-safe item
) 'hms
)
270 (error "Argument must be an HMS form")))
272 (if (eq (car-safe item
) 'date
)
274 (error "Argument must be a date form")))
276 (if (eq (car-safe item
) 'date
)
277 (math-date-to-dt (math-floor (nth 1 item
)))
278 (error "Argument must be a date form")))
280 (if (eq (car-safe item
) 'date
)
281 (append (math-date-to-dt (nth 1 item
))
282 (and (not (math-integerp (nth 1 item
)))
284 (error "Argument must be a date form")))
285 ((eq (car-safe item
) 'vec
)
289 (while (setq item
(cdr item
))
290 (setq res
(calc-unpack-item mode
(car item
))
292 y
(cons (nth 1 res
) y
)))
293 (list (cons 'vec
(nreverse x
))
294 (cons 'vec
(nreverse y
)))))
296 (if (eq (car-safe item
) 'cplx
)
298 (if (eq (car-safe item
) 'polar
)
299 (cdr (math-complex item
))
300 (if (Math-realp item
)
302 (error "Argument must be a complex number")))))
304 (if (or (memq (car-safe item
) '(cplx polar
))
306 (cdr (math-polar item
))
307 (error "Argument must be a complex number")))
309 (if (eq (car-safe item
) 'sdev
)
313 (if (eq (car-safe item
) 'mod
)
315 (error "Argument must be a modulo form")))
316 ((memq mode
'(-6 -
7 -
8 -
9))
317 (if (eq (car-safe item
) 'intv
)
321 (if (eq (car-safe item
) 'frac
)
323 (if (Math-integerp item
)
325 (error "Argument must be a rational number"))))
327 (if (eq (car-safe item
) 'float
)
328 (list (nth 1 item
) (math-normalize (nth 2 item
)))
329 (error "Expected a floating-point number")))
331 (if (eq (car-safe item
) 'float
)
332 (list (calcFunc-mant item
) (calcFunc-xpon item
))
333 (error "Expected a floating-point number")))
335 (error "Invalid unpacking mode: %d" mode
))))
340 (calc-enter-result 1 "diag" (if n
341 (list 'calcFunc-diag
(calc-top-n 1)
342 (prefix-numeric-value n
))
343 (list 'calcFunc-diag
(calc-top-n 1))))))
345 (defun calc-ident (n)
346 (interactive "NDimension of identity matrix = ")
348 (calc-enter-result 0 "idn" (if (eq n
0)
350 (list 'calcFunc-idn
1
351 (prefix-numeric-value n
))))))
353 (defun calc-index (n &optional stack
)
354 (interactive "NSize of vector = \nP")
357 (calc-enter-result 3 "indx" (cons 'calcFunc-index
(calc-top-list-n 3)))
358 (calc-enter-result 0 "indx" (list 'calcFunc-index
359 (prefix-numeric-value n
))))))
361 (defun calc-build-vector (n)
362 (interactive "NSize of vector = ")
364 (calc-enter-result 1 "bldv" (list 'calcFunc-cvec
366 (prefix-numeric-value n
)))))
368 (defun calc-cons (arg)
371 (if (calc-is-hyperbolic)
372 (calc-binary-op "rcns" 'calcFunc-rcons arg
)
373 (calc-binary-op "cons" 'calcFunc-cons arg
))))
376 (defun calc-head (arg)
379 (if (calc-is-inverse)
380 (if (calc-is-hyperbolic)
381 (calc-unary-op "rtai" 'calcFunc-rtail arg
)
382 (calc-unary-op "tail" 'calcFunc-tail arg
))
383 (if (calc-is-hyperbolic)
384 (calc-unary-op "rhed" 'calcFunc-rhead arg
)
385 (calc-unary-op "head" 'calcFunc-head arg
)))))
387 (defun calc-tail (arg)
392 (defun calc-vlength (arg)
395 (if (calc-is-hyperbolic)
396 (calc-unary-op "dims" 'calcFunc-mdims arg
)
397 (calc-unary-op "len" 'calcFunc-vlen arg
))))
399 (defun calc-arrange-vector (n)
400 (interactive "NNumber of columns = ")
402 (calc-enter-result 1 "arng" (list 'calcFunc-arrange
(calc-top-n 1)
403 (prefix-numeric-value n
)))))
405 (defun calc-vector-find (arg)
408 (let ((func (cons 'calcFunc-find
(calc-top-list-n 2))))
411 (if arg
(append func
(list (prefix-numeric-value arg
))) func
)))))
413 (defun calc-subvector ()
416 (if (calc-is-inverse)
417 (calc-enter-result 3 "rsvc" (cons 'calcFunc-rsubvec
418 (calc-top-list-n 3)))
419 (calc-enter-result 3 "svec" (cons 'calcFunc-subvec
(calc-top-list-n 3))))))
421 (defun calc-reverse-vector (arg)
424 (calc-unary-op "rev" 'calcFunc-rev arg
)))
426 (defun calc-mask-vector (arg)
429 (calc-binary-op "vmsk" 'calcFunc-vmask arg
)))
431 (defun calc-expand-vector (arg)
434 (if (calc-is-hyperbolic)
435 (calc-enter-result 3 "vexp" (cons 'calcFunc-vexp
(calc-top-list-n 3)))
436 (calc-binary-op "vexp" 'calcFunc-vexp arg
))))
441 (if (calc-is-inverse)
442 (calc-enter-result 1 "rsrt" (list 'calcFunc-rsort
(calc-top-n 1)))
443 (calc-enter-result 1 "sort" (list 'calcFunc-sort
(calc-top-n 1))))))
448 (if (calc-is-inverse)
449 (calc-enter-result 1 "rgrd" (list 'calcFunc-rgrade
(calc-top-n 1)))
450 (calc-enter-result 1 "grad" (list 'calcFunc-grade
(calc-top-n 1))))))
452 (defun calc-histogram (n)
455 (setq n
(math-read-expr (read-string "Centers of bins: "))))
457 (if calc-hyperbolic-flag
458 (calc-enter-result 2 "hist" (list 'calcFunc-histogram
462 (calc-enter-result 1 "hist" (list 'calcFunc-histogram
466 (defun calc-transpose (arg)
469 (calc-unary-op "trn" 'calcFunc-trn arg
)))
471 (defun calc-conj-transpose (arg)
474 (calc-unary-op "ctrn" 'calcFunc-ctrn arg
)))
476 (defun calc-cross (arg)
479 (calc-binary-op "cros" 'calcFunc-cross arg
)))
481 (defun calc-kron (arg)
484 (calc-binary-op "kron" 'calcFunc-kron arg
)))
486 (defun calc-remove-duplicates (arg)
489 (calc-unary-op "rdup" 'calcFunc-rdup arg
)))
491 (defun calc-set-union (arg)
494 (calc-binary-op "unio" 'calcFunc-vunion arg
'(vec) 'calcFunc-rdup
)))
496 (defun calc-set-intersect (arg)
499 (calc-binary-op "intr" 'calcFunc-vint arg
'(vec) 'calcFunc-rdup
)))
501 (defun calc-set-difference (arg)
504 (calc-binary-op "diff" 'calcFunc-vdiff arg
'(vec) 'calcFunc-rdup
)))
506 (defun calc-set-xor (arg)
509 (calc-binary-op "xor" 'calcFunc-vxor arg
'(vec) 'calcFunc-rdup
)))
511 (defun calc-set-complement (arg)
514 (calc-unary-op "cmpl" 'calcFunc-vcompl arg
)))
516 (defun calc-set-floor (arg)
519 (calc-unary-op "vflr" 'calcFunc-vfloor arg
)))
521 (defun calc-set-enumerate (arg)
524 (calc-unary-op "enum" 'calcFunc-venum arg
)))
526 (defun calc-set-span (arg)
529 (calc-unary-op "span" 'calcFunc-vspan arg
)))
531 (defun calc-set-cardinality (arg)
534 (calc-unary-op "card" 'calcFunc-vcard arg
)))
536 (defun calc-unpack-bits (arg)
539 (if (calc-is-inverse)
540 (calc-unary-op "bpck" 'calcFunc-vpack arg
)
541 (calc-unary-op "bupk" 'calcFunc-vunpack arg
))))
543 (defun calc-pack-bits (arg)
546 (calc-unpack-bits arg
))
549 (defun calc-rnorm (arg)
552 (calc-unary-op "rnrm" 'calcFunc-rnorm arg
)))
554 (defun calc-cnorm (arg)
557 (calc-unary-op "cnrm" 'calcFunc-cnorm arg
)))
559 (defun calc-mrow (n &optional nn
)
560 (interactive "NRow number: \nP")
563 (calc-enter-result 2 "mrow" (cons 'calcFunc-mrow
(calc-top-list-n 2)))
564 (setq n
(prefix-numeric-value n
))
566 (calc-enter-result 1 "getd" (list 'calcFunc-getdiag
(calc-top-n 1)))
568 (calc-enter-result 1 "rrow" (list 'calcFunc-mrrow
569 (calc-top-n 1) (- n
)))
570 (calc-enter-result 1 "mrow" (list 'calcFunc-mrow
571 (calc-top-n 1) n
)))))))
573 (defun calc-mcol (n &optional nn
)
574 (interactive "NColumn number: \nP")
577 (calc-enter-result 2 "mcol" (cons 'calcFunc-mcol
(calc-top-list-n 2)))
578 (setq n
(prefix-numeric-value n
))
580 (calc-enter-result 1 "getd" (list 'calcFunc-getdiag
(calc-top-n 1)))
582 (calc-enter-result 1 "rcol" (list 'calcFunc-mrcol
583 (calc-top-n 1) (- n
)))
584 (calc-enter-result 1 "mcol" (list 'calcFunc-mcol
585 (calc-top-n 1) n
)))))))
590 (defun calcFunc-mdims (m)
592 (math-reject-arg m
'vectorp
))
593 (cons 'vec
(math-mat-dimens m
)))
596 ;;; Apply a function elementwise to vector A. [V X V; N X N] [Public]
597 (defun math-map-vec (f a
)
599 (cons 'vec
(mapcar f
(cdr a
)))
602 (defun math-dimension-error ()
603 (calc-record-why "*Dimension error")
604 (signal 'wrong-type-argument nil
))
607 ;;; Build a vector out of a list of objects. [Public]
608 (defun calcFunc-vec (&rest objs
)
612 ;;; Build a constant vector or matrix. [Public]
613 (defun calcFunc-cvec (obj &rest dims
)
614 (math-make-vec-dimen obj dims
))
616 (defun math-make-vec-dimen (obj dims
)
618 (if (natnump (car dims
))
620 (not (math-numberp obj
)))
621 (cons 'vec
(copy-sequence
622 (make-list (car dims
)
623 (math-make-vec-dimen obj
(cdr dims
)))))
624 (cons 'vec
(make-list (car dims
) obj
)))
625 (math-reject-arg (car dims
) 'fixnatnump
))
628 (defun calcFunc-head (vec)
629 (if (and (Math-vectorp vec
)
632 (calc-record-why 'vectorp vec
)
633 (list 'calcFunc-head vec
)))
635 (defun calcFunc-tail (vec)
636 (if (and (Math-vectorp vec
)
638 (cons 'vec
(cdr (cdr vec
)))
639 (calc-record-why 'vectorp vec
)
640 (list 'calcFunc-tail vec
)))
642 (defun calcFunc-cons (head tail
)
643 (if (Math-vectorp tail
)
644 (cons 'vec
(cons head
(cdr tail
)))
645 (calc-record-why 'vectorp tail
)
646 (list 'calcFunc-cons head tail
)))
648 (defun calcFunc-rhead (vec)
649 (if (and (Math-vectorp vec
)
651 (let ((vec (copy-sequence vec
)))
652 (setcdr (nthcdr (- (length vec
) 2) vec
) nil
)
654 (calc-record-why 'vectorp vec
)
655 (list 'calcFunc-rhead vec
)))
657 (defun calcFunc-rtail (vec)
658 (if (and (Math-vectorp vec
)
660 (nth (1- (length vec
)) vec
)
661 (calc-record-why 'vectorp vec
)
662 (list 'calcFunc-rtail vec
)))
664 (defun calcFunc-rcons (head tail
)
665 (if (Math-vectorp head
)
666 (append head
(list tail
))
667 (calc-record-why 'vectorp head
)
668 (list 'calcFunc-rcons head tail
)))
672 ;;; Apply a function elementwise to vectors A and B. [O X O O] [Public]
673 (defun math-map-vec-2 (f a b
)
677 (while (setq a
(cdr a
))
679 (math-dimension-error))
680 (setq v
(cons (funcall f
(car a
) (car b
)) v
)))
681 (if a
(math-dimension-error))
682 (cons 'vec
(nreverse v
)))
684 (while (setq a
(cdr a
))
685 (setq v
(cons (funcall f
(car a
) b
) v
)))
686 (cons 'vec
(nreverse v
))))
689 (while (setq b
(cdr b
))
690 (setq v
(cons (funcall f a
(car b
)) v
)))
691 (cons 'vec
(nreverse v
)))
696 ;;; "Reduce" a function over a vector (left-associatively). [O X V] [Public]
697 (defun math-reduce-vec (f a
)
700 (let ((accum (car (setq a
(cdr a
)))))
701 (while (setq a
(cdr a
))
702 (setq accum
(funcall f accum
(car a
))))
707 ;;; Reduce a function over the columns of matrix A. [V X V] [Public]
708 (defun math-reduce-cols (f a
)
710 (cons 'vec
(math-reduce-cols-col-step f
(cdr a
) 1 (length (nth 1 a
))))
713 (defun math-reduce-cols-col-step (f a col cols
)
715 (cons (math-reduce-cols-row-step f
(nth col
(car a
)) col
(cdr a
))
716 (math-reduce-cols-col-step f a
(1+ col
) cols
))))
718 (defun math-reduce-cols-row-step (f tot col a
)
720 (math-reduce-cols-row-step f
721 (funcall f tot
(nth col
(car a
)))
728 (defun math-dot-product (a b
)
729 (if (setq a
(cdr a
) b
(cdr b
))
730 (let ((accum (math-mul (car a
) (car b
))))
731 (while (setq a
(cdr a
) b
(cdr b
))
732 (setq accum
(math-add accum
(math-mul (car a
) (car b
)))))
737 ;;; Return the number of elements in vector V. [Public]
738 (defun calcFunc-vlen (v)
743 (list 'calcFunc-vlen v
))))
745 ;;; Get the Nth row of a matrix.
746 (defun calcFunc-mrow (mat n
) ; [Public]
748 (math-map-vec (function (lambda (x) (calcFunc-mrow mat x
))) n
)
749 (if (and (eq (car-safe n
) 'intv
) (math-constp n
))
751 (math-add (nth 2 n
) (if (memq (nth 1 n
) '(2 3)) 0 1))
752 (math-add (nth 3 n
) (if (memq (nth 1 n
) '(1 3)) 1 0)))
753 (or (and (integerp (setq n
(math-check-integer n
)))
755 (math-reject-arg n
'fixposintp
))
756 (or (Math-vectorp mat
)
757 (math-reject-arg mat
'vectorp
))
759 (math-reject-arg n
"*Index out of range")))))
761 (defun calcFunc-subscr (mat n
&optional m
)
762 (if (eq (car-safe mat
) 'var
) nil
763 (setq mat
(calcFunc-mrow mat n
))
765 (if (math-num-integerp n
)
766 (calcFunc-mrow mat m
)
767 (calcFunc-mcol mat m
))
770 ;;; Get the Nth column of a matrix.
771 (defun math-mat-col (mat n
)
772 (cons 'vec
(mapcar (function (lambda (x) (elt x n
))) (cdr mat
))))
774 (defun calcFunc-mcol (mat n
) ; [Public]
777 (math-map-vec (function (lambda (x) (calcFunc-mcol mat x
))) n
))
778 (if (and (eq (car-safe n
) 'intv
) (math-constp n
))
779 (if (math-matrixp mat
)
780 (math-map-vec (function (lambda (x) (calcFunc-mrow x n
))) mat
)
781 (calcFunc-mrow mat n
))
782 (or (and (integerp (setq n
(math-check-integer n
)))
784 (math-reject-arg n
'fixposintp
))
785 (or (Math-vectorp mat
)
786 (math-reject-arg mat
'vectorp
))
787 (or (if (math-matrixp mat
)
788 (and (< n
(length (nth 1 mat
)))
789 (math-mat-col mat n
))
791 (math-reject-arg n
"*Index out of range")))))
793 ;;; Remove the Nth row from a matrix.
794 (defun math-mat-less-row (mat n
)
798 (math-mat-less-row (cdr mat
) (1- n
)))))
800 (defun calcFunc-mrrow (mat n
) ; [Public]
801 (and (integerp (setq n
(math-check-integer n
)))
804 (math-mat-less-row mat n
)))
806 ;;; Remove the Nth column from a matrix.
807 (defun math-mat-less-col (mat n
)
808 (cons 'vec
(mapcar (function (lambda (x) (math-mat-less-row x n
)))
811 (defun calcFunc-mrcol (mat n
) ; [Public]
812 (and (integerp (setq n
(math-check-integer n
)))
814 (if (math-matrixp mat
)
815 (and (< n
(length (nth 1 mat
)))
816 (math-mat-less-col mat n
))
817 (math-mat-less-row mat n
))))
819 (defun calcFunc-getdiag (mat) ; [Public]
820 (if (math-square-matrixp mat
)
821 (cons 'vec
(math-get-diag-step (cdr mat
) 1))
822 (calc-record-why 'square-matrixp mat
)
823 (list 'calcFunc-getdiag mat
)))
825 (defun math-get-diag-step (row n
)
827 (cons (nth n
(car row
))
828 (math-get-diag-step (cdr row
) (1+ n
)))))
830 (defun math-transpose (mat) ; [Public]
832 (col (length (nth 1 mat
))))
833 (while (> (setq col
(1- col
)) 0)
834 (setq m
(cons (math-mat-col mat col
) m
)))
837 (defun calcFunc-trn (mat)
838 (if (math-vectorp mat
)
839 (if (math-matrixp mat
)
841 (math-col-matrix mat
))
842 (if (math-numberp mat
)
844 (math-reject-arg mat
'matrixp
))))
846 (defun calcFunc-ctrn (mat)
847 (calcFunc-conj (calcFunc-trn mat
)))
849 (defun calcFunc-pack (mode els
)
850 (or (Math-vectorp els
) (math-reject-arg els
'vectorp
))
851 (if (and (Math-vectorp mode
) (cdr mode
))
852 (setq mode
(cdr mode
))
853 (or (integerp mode
) (math-reject-arg mode
'fixnump
)))
855 (if (= (calc-pack-size mode
) (1- (length els
)))
856 (calc-pack-items mode
(cdr els
))
857 (math-reject-arg els
"*Wrong number of elements"))
858 (error (math-reject-arg els
(nth 1 err
)))))
860 (defun calcFunc-unpack (mode thing
)
861 (or (integerp mode
) (math-reject-arg mode
'fixnump
))
863 (cons 'vec
(calc-unpack-item mode thing
))
864 (error (math-reject-arg thing
(nth 1 err
)))))
866 (defun calcFunc-unpackt (mode thing
)
867 (let ((calc-unpack-with-type 'pair
))
868 (calcFunc-unpack mode thing
)))
870 (defun calcFunc-arrange (vec cols
) ; [Public]
871 (setq cols
(math-check-fixnum cols t
))
872 (if (math-vectorp vec
)
873 (let* ((flat (math-flatten-vector vec
))
878 (while (>= (length flat
) cols
)
879 (setq next
(nthcdr cols flat
))
880 (setcdr (nthcdr (1- cols
) flat
) nil
)
881 (setq mat
(nconc mat
(list (cons 'vec flat
)))
884 (setq mat
(nconc mat
(list (cons 'vec flat
)))))
887 (defun math-flatten-vector (vec) ; [L V]
888 (if (math-vectorp vec
)
889 (apply 'append
(mapcar 'math-flatten-vector
(cdr vec
)))
892 (defun calcFunc-vconcat (a b
)
893 (math-normalize (list '| a b
)))
895 (defun calcFunc-vconcatrev (a b
)
896 (math-normalize (list '| b a
)))
898 (defun calcFunc-append (v1 v2
)
899 (if (and (math-vectorp v1
) (math-vectorp v2
))
901 (list 'calcFunc-append v1 v2
)))
903 (defun calcFunc-appendrev (v1 v2
)
904 (calcFunc-append v2 v1
))
907 ;;; Copy a matrix. [Public]
908 (defun math-copy-matrix (m)
909 (if (math-vectorp (nth 1 m
))
910 (cons 'vec
(mapcar 'copy-sequence
(cdr m
)))
913 ;;; Convert a scalar or vector into an NxN diagonal matrix. [Public]
914 (defun calcFunc-diag (a &optional n
)
915 (and n
(not (integerp n
))
916 (setq n
(math-check-fixnum n
)))
918 (if (and n
(/= (length a
) (1+ n
)))
919 (list 'calcFunc-diag a n
)
921 (if (and n
(/= (length (elt a
1)) (1+ n
)))
922 (list 'calcFunc-diag a n
)
924 (cons 'vec
(math-diag-step (cdr a
) 0 (1- (length a
))))))
926 (cons 'vec
(math-diag-step (make-list n a
) 0 n
))
927 (list 'calcFunc-diag a
))))
929 (defun calcFunc-idn (a &optional n
)
932 (math-reject-arg a
'numberp
)
934 (if (integerp calc-matrix-mode
)
935 (calcFunc-idn a calc-matrix-mode
)
936 (list 'calcFunc-idn a
))))
938 (defun math-mimic-ident (a m
)
939 (if (math-square-matrixp m
)
940 (calcFunc-idn a
(1- (length m
)))
943 (cons 'vec
(mapcar (function (lambda (x)
945 (math-mimic-ident a x
)
948 (math-dimension-error))
951 (defun math-diag-step (a n m
)
954 (nconc (make-list n
0)
956 (make-list (1- (- m n
)) 0))))
957 (math-diag-step (cdr a
) (1+ n
) m
))
960 ;;; Create a vector of consecutive integers. [Public]
961 (defun calcFunc-index (n &optional start incr
)
962 (if (math-messy-integerp n
)
963 (math-float (calcFunc-index (math-trunc n
) start incr
))
964 (and (not (integerp n
))
965 (setq n
(math-check-fixnum n
)))
970 (while (>= (setq n
(1- n
)) 0)
971 (setq vec
(cons start vec
)
972 start
(math-add start
(or incr
1))))
973 (while (<= (setq n
(1+ n
)) 0)
974 (setq vec
(cons start vec
)
975 start
(math-mul start
(or incr
2)))))
976 (setq vec
(nreverse vec
)))
979 (setq vec
(cons n vec
)
983 (setq vec
(cons i vec
)
987 ;;; Find an element in a vector.
988 (defun calcFunc-find (vec x
&optional start
)
989 (setq start
(if start
(math-check-fixnum start t
) 1))
990 (if (< start
1) (math-reject-arg start
'posp
))
991 (setq vec
(nthcdr start vec
))
993 (while (and vec
(not (Math-equal x
(car vec
))))
998 ;;; Return a subvector of a vector.
999 (defun calcFunc-subvec (vec start
&optional end
)
1000 (setq start
(math-check-fixnum start t
)
1001 end
(math-check-fixnum (or end
0) t
))
1002 (or (math-vectorp vec
) (math-reject-arg vec
'vectorp
))
1003 (let ((len (1- (length vec
))))
1005 (setq start
(+ len start
1)))
1007 (setq end
(+ len end
1)))
1008 (if (or (> start len
)
1011 (setq vec
(nthcdr start vec
))
1013 (let ((chop (nthcdr (- end start
1) (setq vec
(copy-sequence vec
)))))
1017 ;;; Remove a subvector from a vector.
1018 (defun calcFunc-rsubvec (vec start
&optional end
)
1019 (setq start
(math-check-fixnum start t
)
1020 end
(math-check-fixnum (or end
0) t
))
1021 (or (math-vectorp vec
) (math-reject-arg vec
'vectorp
))
1022 (let ((len (1- (length vec
))))
1024 (setq start
(+ len start
1)))
1026 (setq end
(+ len end
1)))
1027 (if (or (> start len
)
1030 (let ((tail (nthcdr end vec
))
1031 (chop (nthcdr (1- start
) (setq vec
(copy-sequence vec
)))))
1033 (append vec tail
)))))
1035 ;;; Reverse the order of the elements of a vector.
1036 (defun calcFunc-rev (vec)
1037 (if (math-vectorp vec
)
1038 (cons 'vec
(reverse (cdr vec
)))
1039 (math-reject-arg vec
'vectorp
)))
1041 ;;; Compress a vector according to a mask vector.
1042 (defun calcFunc-vmask (mask vec
)
1043 (if (math-numberp mask
)
1044 (if (math-zerop mask
)
1047 (or (math-vectorp mask
) (math-reject-arg mask
'vectorp
))
1048 (or (math-constp mask
) (math-reject-arg mask
'constp
))
1049 (or (math-vectorp vec
) (math-reject-arg vec
'vectorp
))
1050 (or (= (length mask
) (length vec
)) (math-dimension-error))
1052 (while (setq mask
(cdr mask
) vec
(cdr vec
))
1053 (or (math-zerop (car mask
))
1054 (setq new
(cons (car vec
) new
))))
1055 (cons 'vec
(nreverse new
)))))
1057 ;;; Expand a vector according to a mask vector.
1058 (defun calcFunc-vexp (mask vec
&optional filler
)
1059 (or (math-vectorp mask
) (math-reject-arg mask
'vectorp
))
1060 (or (math-constp mask
) (math-reject-arg mask
'constp
))
1061 (or (math-vectorp vec
) (math-reject-arg vec
'vectorp
))
1063 (fvec (and filler
(math-vectorp filler
))))
1064 (while (setq mask
(cdr mask
))
1065 (if (math-zerop (car mask
))
1066 (setq new
(cons (or (if fvec
1067 (car (setq filler
(cdr filler
)))
1071 new
(cons (or (car vec
) (car mask
)) new
))))
1072 (cons 'vec
(nreverse new
))))
1075 ;;; Compute the row and column norms of a vector or matrix. [Public]
1076 (defun calcFunc-rnorm (a)
1077 (if (and (Math-vectorp a
)
1079 (if (math-matrixp a
)
1080 (math-reduce-vec 'math-max
(math-map-vec 'calcFunc-cnorm a
))
1081 (math-reduce-vec 'math-max
(math-map-vec 'math-abs a
)))
1082 (calc-record-why 'vectorp a
)
1083 (list 'calcFunc-rnorm a
)))
1085 (defun calcFunc-cnorm (a)
1086 (if (and (Math-vectorp a
)
1088 (if (math-matrixp a
)
1089 (math-reduce-vec 'math-max
1090 (math-reduce-cols 'math-add-abs a
))
1091 (math-reduce-vec 'math-add-abs a
))
1092 (calc-record-why 'vectorp a
)
1093 (list 'calcFunc-cnorm a
)))
1095 (defun math-add-abs (a b
)
1096 (math-add (math-abs a
) (math-abs b
)))
1099 ;;; Sort the elements of a vector into increasing order.
1100 (defun calcFunc-sort (vec) ; [Public]
1101 (if (math-vectorp vec
)
1102 (cons 'vec
(sort (copy-sequence (cdr vec
)) 'math-beforep
))
1103 (math-reject-arg vec
'vectorp
)))
1105 (defun calcFunc-rsort (vec) ; [Public]
1106 (if (math-vectorp vec
)
1107 (cons 'vec
(nreverse (sort (copy-sequence (cdr vec
)) 'math-beforep
)))
1108 (math-reject-arg vec
'vectorp
)))
1110 ;; The variable math-grade-vec is local to calcFunc-grade and
1111 ;; calcFunc-rgrade, but is used by math-grade-beforep, which is called
1112 ;; by calcFunc-grade and calcFunc-rgrade.
1113 (defvar math-grade-vec
)
1115 (defun calcFunc-grade (math-grade-vec)
1116 (if (math-vectorp math-grade-vec
)
1117 (let* ((len (1- (length math-grade-vec
))))
1118 (cons 'vec
(sort (cdr (calcFunc-index len
)) 'math-grade-beforep
)))
1119 (math-reject-arg math-grade-vec
'vectorp
)))
1121 (defun calcFunc-rgrade (math-grade-vec)
1122 (if (math-vectorp math-grade-vec
)
1123 (let* ((len (1- (length math-grade-vec
))))
1124 (cons 'vec
(nreverse (sort (cdr (calcFunc-index len
))
1125 'math-grade-beforep
))))
1126 (math-reject-arg math-grade-vec
'vectorp
)))
1128 (defun math-grade-beforep (i j
)
1129 (math-beforep (nth i math-grade-vec
) (nth j math-grade-vec
)))
1132 ;;; Compile a histogram of data from a vector.
1133 (defun calcFunc-histogram (vec wts
&optional n
)
1134 (or n
(setq n wts wts
1))
1135 (or (Math-vectorp vec
)
1136 (math-reject-arg vec
'vectorp
))
1137 (if (Math-vectorp wts
)
1138 (or (= (length vec
) (length wts
))
1139 (math-dimension-error)))
1141 (let ((res (make-vector n
0))
1143 (wvec (Math-vectorp wts
))
1146 (while (setq vp
(cdr vp
))
1149 (setq bin
(math-floor bin
)))
1153 (math-add (aref res bin
)
1154 (if wvec
(car (setq wp
(cdr wp
))) wts
)))))
1155 (cons 'vec
(append res nil
))))
1156 ((Math-vectorp n
) ;; n is a vector of midpoints
1157 (let* ((bds (math-vector-avg n
))
1158 (res (make-vector (1- (length n
)) 0))
1160 (wvec (Math-vectorp wts
))
1165 (let ((tbds (cdr bds
))
1167 (while (and tbds
(Math-lessp (car tbds
) num
))
1169 (setq tbds
(cdr tbds
)))
1171 (math-add (aref res i
)
1172 (if wvec
(car (setq wp
(cdr wp
))) wts
))))
1174 (cons 'vec
(append res nil
))))
1176 (math-reject-arg n
"*Expecting an integer or vector"))))
1178 ;;; Replace a vector [a b c ...] with a vector of averages
1179 ;;; [(a+b)/2 (b+c)/2 ...]
1180 (defun math-vector-avg (vec)
1181 (let ((vp (sort (copy-sequence (cdr vec
)) 'math-beforep
))
1183 (while (and vp
(cdr vp
))
1184 (setq res
(cons (math-div (math-add (car vp
) (cadr vp
)) 2) res
)
1186 (cons 'vec
(reverse res
))))
1191 (defun calcFunc-vunion (a b
)
1192 (if (Math-objectp a
)
1193 (setq a
(list 'vec a
))
1194 (or (math-vectorp a
) (math-reject-arg a
'vectorp
)))
1195 (if (Math-objectp b
)
1197 (or (math-vectorp b
) (math-reject-arg b
'vectorp
))
1199 (calcFunc-rdup (append a b
)))
1201 (defun calcFunc-vint (a b
)
1202 (if (and (math-simple-set a
) (math-simple-set b
))
1204 (setq a
(cdr (calcFunc-rdup a
)))
1205 (setq b
(cdr (calcFunc-rdup b
)))
1206 (let ((vec (list 'vec
)))
1208 (if (math-beforep (car a
) (car b
))
1210 (if (Math-equal (car a
) (car b
))
1211 (setq vec
(cons (car a
) vec
)
1215 (calcFunc-vcompl (calcFunc-vunion (calcFunc-vcompl a
)
1216 (calcFunc-vcompl b
)))))
1218 (defun calcFunc-vdiff (a b
)
1219 (if (and (math-simple-set a
) (math-simple-set b
))
1221 (setq a
(cdr (calcFunc-rdup a
)))
1222 (setq b
(cdr (calcFunc-rdup b
)))
1223 (let ((vec (list 'vec
)))
1225 (while (and b
(math-beforep (car b
) (car a
)))
1227 (if (and b
(Math-equal (car a
) (car b
)))
1230 (setq vec
(cons (car a
) vec
)
1233 (calcFunc-vcompl (calcFunc-vunion (calcFunc-vcompl a
) b
))))
1235 (defun calcFunc-vxor (a b
)
1236 (if (and (math-simple-set a
) (math-simple-set b
))
1238 (setq a
(cdr (calcFunc-rdup a
)))
1239 (setq b
(cdr (calcFunc-rdup b
)))
1240 (let ((vec (list 'vec
)))
1244 (math-beforep (car a
) (car b
))))
1245 (setq vec
(cons (car a
) vec
)
1247 (if (and a
(Math-equal (car a
) (car b
)))
1249 (setq vec
(cons (car b
) vec
)))
1252 (let ((ca (calcFunc-vcompl a
))
1253 (cb (calcFunc-vcompl b
)))
1254 (calcFunc-vunion (calcFunc-vcompl (calcFunc-vunion ca b
))
1255 (calcFunc-vcompl (calcFunc-vunion a cb
))))))
1257 (defun calcFunc-vcompl (a)
1258 (setq a
(math-prepare-set a
))
1259 (let ((vec (list 'vec
))
1260 (prev '(neg (var inf var-inf
)))
1262 (while (setq a
(cdr a
))
1263 (or (and (equal (nth 2 (car a
)) '(neg (var inf var-inf
)))
1264 (memq (nth 1 (car a
)) '(2 3)))
1265 (setq vec
(cons (list 'intv
1267 (if (memq (nth 1 (car a
)) '(0 1)) 1 0))
1271 (setq prev
(nth 3 (car a
))
1272 closed
(if (memq (nth 1 (car a
)) '(0 2)) 2 0)))
1273 (or (and (equal prev
'(var inf var-inf
))
1275 (setq vec
(cons (list 'intv
(+ closed
1)
1276 prev
'(var inf var-inf
))
1278 (math-clean-set (nreverse vec
))))
1280 (defun calcFunc-vspan (a)
1281 (setq a
(math-prepare-set a
))
1283 (let ((last (nth (1- (length a
)) a
)))
1284 (math-make-intv (+ (logand (nth 1 (nth 1 a
)) 2)
1285 (logand (nth 1 last
) 1))
1290 (defun calcFunc-vfloor (a &optional always-vec
)
1291 (setq a
(math-prepare-set a
))
1292 (let ((vec (list 'vec
)) (p a
) (prev nil
) b mask
)
1293 (while (setq p
(cdr p
))
1294 (setq mask
(nth 1 (car p
))
1297 (and (memq mask
'(0 1))
1298 (not (math-infinitep a
))
1299 (setq mask
(logior mask
2))
1300 (math-num-integerp a
)
1301 (setq a
(math-add a
1)))
1302 (setq a
(math-ceiling a
))
1303 (and (memq mask
'(0 2))
1304 (not (math-infinitep b
))
1305 (setq mask
(logior mask
1))
1306 (math-num-integerp b
)
1307 (setq b
(math-sub b
1)))
1308 (setq b
(math-floor b
))
1309 (if (and prev
(Math-equal (math-sub a
1) (nth 3 prev
)))
1310 (setcar (nthcdr 3 prev
) b
)
1311 (or (Math-lessp b a
)
1312 (setq vec
(cons (setq prev
(list 'intv mask a b
)) vec
)))))
1313 (setq vec
(nreverse vec
))
1314 (math-clean-set vec always-vec
)))
1316 (defun calcFunc-vcard (a)
1317 (setq a
(calcFunc-vfloor a t
))
1318 (or (math-constp a
) (math-reject-arg a
"*Set must be finite"))
1320 (while (setq a
(cdr a
))
1321 (if (eq (car-safe (car a
)) 'intv
)
1322 (setq count
(math-add count
(math-sub (nth 3 (car a
))
1324 (setq count
(math-add count
1)))
1327 (defun calcFunc-venum (a)
1328 (setq a
(calcFunc-vfloor a t
))
1329 (or (math-constp a
) (math-reject-arg a
"*Set must be finite"))
1330 (let* ((prev a
) (this (cdr prev
)) this-val next this-last
)
1332 (setq next
(cdr this
)
1333 this-val
(car this
))
1334 (if (eq (car-safe this-val
) 'intv
)
1336 (setq this
(cdr (calcFunc-index (math-add
1337 (math-sub (nth 3 this-val
)
1341 (setq this-last
(last this
))
1342 (setcdr this-last next
)
1344 (setq prev this-last
))
1349 (defun calcFunc-vpack (a)
1350 (setq a
(calcFunc-vfloor a t
))
1352 (math-negp (if (eq (car-safe (nth 1 a
)) 'intv
)
1355 (math-reject-arg (nth 1 a
) 'posp
))
1357 (while (setq a
(cdr a
))
1358 (if (eq (car-safe (car a
)) 'intv
)
1359 (if (equal (nth 3 (car a
)) '(var inf var-inf
))
1360 (setq accum
(math-sub accum
1361 (math-power-of-2 (nth 2 (car a
)))))
1362 (setq accum
(math-add accum
1364 (math-power-of-2 (1+ (nth 3 (car a
))))
1365 (math-power-of-2 (nth 2 (car a
)))))))
1366 (setq accum
(math-add accum
(math-power-of-2 (car a
))))))
1369 (defun calcFunc-vunpack (a &optional w
)
1370 (or (math-num-integerp a
) (math-reject-arg a
'integerp
))
1371 (if w
(setq a
(math-clip a w
)))
1372 (if (math-messy-integerp a
) (setq a
(math-trunc a
)))
1373 (let* ((calc-number-radix 2)
1374 (calc-twos-complement-mode nil
)
1376 (aa (if neg
(math-sub -
1 a
) a
))
1380 (math-format-bignum-binary (cdr aa
))
1381 (math-format-binary aa
))))
1382 (zero (if neg ?
1 ?
0))
1383 (one (if neg ?
0 ?
1))
1386 (pos (1- len
)) pos2
)
1388 (if (eq (aref str pos
) zero
)
1391 (while (and (>= pos
0) (eq (aref str pos
) one
))
1392 (setq pos
(1- pos
)))
1393 (setq vec
(cons (if (= pos
(1- pos2
))
1395 (list 'intv
3 (- len pos2
1) (- len pos
2)))
1398 (setq vec
(cons (list 'intv
2 len
'(var inf var-inf
)) vec
)))
1399 (math-clean-set (nreverse vec
))))
1401 (defun calcFunc-rdup (a)
1402 (if (math-simple-set a
)
1404 (and (Math-objectp a
) (setq a
(list 'vec a
)))
1405 (or (math-vectorp a
) (math-reject-arg a
'vectorp
))
1406 (setq a
(sort (copy-sequence (cdr a
)) 'math-beforep
))
1409 (if (Math-equal (car p
) (nth 1 p
))
1410 (setcdr p
(cdr (cdr p
)))
1413 (math-clean-set (math-prepare-set a
))))
1415 (defun math-prepare-set (a)
1416 (if (Math-objectp a
)
1417 (setq a
(list 'vec a
))
1418 (or (math-vectorp a
) (math-reject-arg a
'vectorp
))
1419 (setq a
(cons 'vec
(sort (copy-sequence (cdr a
)) 'math-beforep
))))
1422 ;; Convert all elements to non-empty intervals.
1424 (if (eq (car-safe (nth 1 p
)) 'intv
)
1425 (if (math-intv-constp (nth 1 p
))
1426 (if (and (memq (nth 1 (nth 1 p
)) '(0 1 2))
1427 (Math-equal (nth 2 (nth 1 p
)) (nth 3 (nth 1 p
))))
1428 (setcdr p
(cdr (cdr p
)))
1430 (math-reject-arg (nth 1 p
) 'constp
))
1431 (or (Math-anglep (nth 1 p
))
1432 (eq (car (nth 1 p
)) 'date
)
1433 (equal (nth 1 p
) '(var inf var-inf
))
1434 (equal (nth 1 p
) '(neg (var inf var-inf
)))
1435 (math-reject-arg (nth 1 p
) 'realp
))
1436 (setcar (cdr p
) (list 'intv
3 (nth 1 p
) (nth 1 p
)))
1439 ;; Combine redundant intervals.
1441 (while (cdr (cdr p
))
1442 (if (or (memq (setq res
(math-compare (nth 3 (nth 1 p
))
1446 (memq (nth 1 (nth 1 p
)) '(0 2))
1447 (memq (nth 1 (nth 2 p
)) '(0 1))))
1449 (setq res
(math-compare (nth 3 (nth 1 p
)) (nth 3 (nth 2 p
))))
1450 (setcdr p
(cons (list 'intv
1451 (+ (logand (logior (nth 1 (nth 1 p
))
1458 (logand (logior (if (memq res
'(1 0 2))
1459 (nth 1 (nth 1 p
)) 0)
1460 (if (memq res
'(-1 0 2))
1461 (nth 1 (nth 2 p
)) 0))
1467 (cdr (cdr (cdr p
))))))))
1470 (defun math-clean-set (a &optional always-vec
)
1473 (if (and (eq (car-safe (nth 1 p
)) 'intv
)
1474 (Math-equal (nth 2 (nth 1 p
)) (nth 3 (nth 1 p
))))
1475 (setcar (cdr p
) (nth 2 (nth 1 p
))))
1477 (if (and (not (cdr (cdr a
)))
1478 (eq (car-safe (nth 1 a
)) 'intv
)
1483 (defun math-simple-set (a)
1484 (or (and (Math-objectp a
)
1485 (not (eq (car-safe a
) 'intv
)))
1486 (and (Math-vectorp a
)
1488 (while (and (setq a
(cdr a
))
1489 (not (eq (car-safe (car a
)) 'intv
))))
1495 ;;; Compute a right-handed vector cross product. [O O O] [Public]
1496 (defun calcFunc-cross (a b
)
1497 (if (and (eq (car-safe a
) 'vec
)
1499 (if (and (eq (car-safe b
) 'vec
)
1502 (math-sub (math-mul (nth 2 a
) (nth 3 b
))
1503 (math-mul (nth 3 a
) (nth 2 b
)))
1504 (math-sub (math-mul (nth 3 a
) (nth 1 b
))
1505 (math-mul (nth 1 a
) (nth 3 b
)))
1506 (math-sub (math-mul (nth 1 a
) (nth 2 b
))
1507 (math-mul (nth 2 a
) (nth 1 b
))))
1508 (math-reject-arg b
"*Three-vector expected"))
1509 (math-reject-arg a
"*Three-vector expected")))
1512 ;;; Compute a Kronecker product
1513 (defun calcFunc-kron (x y
&optional nocheck
)
1514 "The Kronecker product of objects X and Y.
1515 The objects X and Y may be scalars, vectors or matrices.
1516 The type of the result depends on the types of the operands;
1517 the product of two scalars is a scalar,
1518 of one scalar and a vector is a vector,
1519 of two vectors is a vector.
1520 of one vector and a matrix is a matrix,
1521 of two matrices is a matrix."
1523 (cond ((or (math-matrixp x
)
1525 (unless (math-matrixp x
)
1526 (setq x
(if (math-vectorp x
)
1528 (list 'vec
(list 'vec x
)))))
1529 (unless (math-matrixp y
)
1530 (setq y
(if (math-vectorp y
)
1532 (list 'vec
(list 'vec y
))))))
1533 ((or (math-vectorp x
)
1535 (unless (math-vectorp x
)
1536 (setq x
(list 'vec x
)))
1537 (unless (math-vectorp y
)
1538 (setq y
(list 'vec y
))))))
1539 (if (math-vectorp x
)
1543 (setq ret
(cons (calcFunc-kron v w t
) ret
))))
1544 (cons 'vec
(nreverse ret
)))
1548 ;; The variable math-rb-close is local to math-read-brackets, but
1549 ;; is used by math-read-vector, which is called (directly and
1550 ;; indirectly) by math-read-brackets.
1551 (defvar math-rb-close
)
1553 ;; The next few variables are local to math-read-exprs in calc-aent.el
1554 ;; and math-read-expr in calc-ext.el, but are set in functions they call.
1555 (defvar math-exp-pos
)
1556 (defvar math-exp-str
)
1557 (defvar math-exp-old-pos
)
1558 (defvar math-exp-token
)
1559 (defvar math-exp-keep-spaces
)
1560 (defvar math-expr-data
)
1562 (defun math-read-brackets (space-sep math-rb-close
)
1563 (and space-sep
(setq space-sep
(not (math-check-for-commas))))
1565 (while (eq math-exp-token
'space
)
1567 (if (or (equal math-expr-data math-rb-close
)
1568 (eq math-exp-token
'end
))
1572 (let ((save-exp-pos math-exp-pos
)
1573 (save-exp-old-pos math-exp-old-pos
)
1574 (save-exp-token math-exp-token
)
1575 (save-exp-data math-expr-data
)
1576 (vals (let ((math-exp-keep-spaces space-sep
))
1577 (if (or (equal math-expr-data
"\\dots")
1578 (equal math-expr-data
"\\ldots"))
1579 '(vec (neg (var inf var-inf
)))
1580 (catch 'syntax
(math-read-vector))))))
1583 (let ((error-exp-pos math-exp-pos
)
1584 (error-exp-old-pos math-exp-old-pos
)
1586 (setq math-exp-pos save-exp-pos
1587 math-exp-old-pos save-exp-old-pos
1588 math-exp-token save-exp-token
1589 math-expr-data save-exp-data
)
1590 (let ((math-exp-keep-spaces nil
))
1591 (setq vals2
(catch 'syntax
(math-read-vector))))
1592 (if (and (not (stringp vals2
))
1593 (or (assoc math-expr-data
'(("\\ldots") ("\\dots") (";")))
1594 (equal math-expr-data math-rb-close
)
1595 (eq math-exp-token
'end
)))
1598 (setq math-exp-pos error-exp-pos
1599 math-exp-old-pos error-exp-old-pos
)
1600 (throw 'syntax vals
)))
1601 (throw 'syntax vals
)))
1602 (if (or (equal math-expr-data
"\\dots")
1603 (equal math-expr-data
"\\ldots"))
1606 (setq vals
(if (> (length vals
) 2)
1607 (cons 'calcFunc-mul
(cdr vals
)) (nth 1 vals
)))
1608 (let ((exp2 (if (or (equal math-expr-data math-rb-close
)
1609 (equal math-expr-data
")")
1610 (eq math-exp-token
'end
))
1612 (math-read-expr-level 0))))
1615 (if (equal math-expr-data
")") 2 3)
1618 (if (not (or (equal math-expr-data math-rb-close
)
1619 (equal math-expr-data
")")
1620 (eq math-exp-token
'end
)))
1621 (throw 'syntax
"Expected `]'")))
1622 (if (equal math-expr-data
";")
1623 (let ((math-exp-keep-spaces space-sep
))
1624 (setq vals
(cons 'vec
(math-read-matrix (list vals
))))))
1625 (if (not (or (equal math-expr-data math-rb-close
)
1626 (eq math-exp-token
'end
)))
1627 (throw 'syntax
"Expected `]'")))
1628 (or (eq math-exp-token
'end
)
1632 (defun math-check-for-commas (&optional balancing
)
1634 (pos (1- math-exp-pos
)))
1635 (while (and (>= count
0)
1636 (setq pos
(string-match
1637 (if balancing
"[],[{}()<>]" "[],[{}()]")
1638 math-exp-str
(1+ pos
)))
1639 (or (/= (aref math-exp-str pos
) ?
,) (> count
0) balancing
))
1640 (cond ((memq (aref math-exp-str pos
) '(?\
[ ?\
{ ?\
( ?\
<))
1641 (setq count
(1+ count
)))
1642 ((memq (aref math-exp-str pos
) '(?\
] ?\
} ?\
) ?\
>))
1643 (setq count
(1- count
)))))
1646 (and pos
(= (aref math-exp-str pos
) ?
,)))))
1648 (defun math-read-vector ()
1649 (let* ((val (list (math-read-expr-level 0)))
1652 (while (eq math-exp-token
'space
)
1654 (and (not (eq math-exp-token
'end
))
1655 (not (equal math-expr-data
";"))
1656 (not (equal math-expr-data math-rb-close
))
1657 (not (equal math-expr-data
"\\dots"))
1658 (not (equal math-expr-data
"\\ldots"))))
1659 (if (equal math-expr-data
",")
1661 (while (eq math-exp-token
'space
)
1663 (let ((rest (list (math-read-expr-level 0))))
1668 (defun math-read-matrix (mat)
1669 (while (equal math-expr-data
";")
1671 (while (eq math-exp-token
'space
)
1673 (setq mat
(nconc mat
(list (math-read-vector)))))
1678 ;;; calc-vec.el ends here