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