(calc-get-operator): Add `calc-symclip'.
[bpt/emacs.git] / lisp / calc / calc-map.el
1 ;;; calc-map.el --- higher-order functions for Calc
2
3 ;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004,
4 ;; 2005, 2006, 2007, 2008, 2009 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 3 of the License, or
14 ;; (at your option) 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. If not, see <http://www.gnu.org/licenses/>.
23
24 ;;; Commentary:
25
26 ;;; Code:
27
28 ;; This file is autoloaded from calc-ext.el.
29
30 (require 'calc-ext)
31 (require 'calc-macs)
32
33 (defun calc-apply (&optional oper)
34 (interactive)
35 (calc-wrapper
36 (let* ((sel-mode nil)
37 (calc-dollar-values (mapcar 'calc-get-stack-element
38 (nthcdr calc-stack-top calc-stack)))
39 (calc-dollar-used 0)
40 (oper (or oper (calc-get-operator "Apply"
41 (if (math-vectorp (calc-top 1))
42 (1- (length (calc-top 1)))
43 -1))))
44 (expr (calc-top-n (1+ calc-dollar-used))))
45 (message "Working...")
46 (calc-set-command-flag 'clear-message)
47 (calc-enter-result (1+ calc-dollar-used)
48 (concat (substring "apl" 0 (- 4 (length (nth 2 oper))))
49 (nth 2 oper))
50 (list 'calcFunc-apply
51 (math-calcFunc-to-var (nth 1 oper))
52 expr)))))
53
54 (defun calc-reduce (&optional oper accum)
55 (interactive)
56 (calc-wrapper
57 (let* ((sel-mode nil)
58 (nest (calc-is-hyperbolic))
59 (rev (calc-is-inverse))
60 (nargs (if (and nest (not rev)) 2 1))
61 (calc-dollar-values (mapcar 'calc-get-stack-element
62 (nthcdr calc-stack-top calc-stack)))
63 (calc-dollar-used 0)
64 (calc-mapping-dir (and (not accum) (not nest) ""))
65 (oper (or oper (calc-get-operator
66 (if nest
67 (concat (if accum "Accumulate " "")
68 (if rev "Fixed Point" "Nest"))
69 (concat (if rev "Inv " "")
70 (if accum "Accumulate" "Reduce")))
71 (if nest 1 2)))))
72 (message "Working...")
73 (calc-set-command-flag 'clear-message)
74 (calc-enter-result (+ calc-dollar-used nargs)
75 (concat (substring (if nest
76 (if rev "fxp" "nst")
77 (if accum "acc" "red"))
78 0 (- 4 (length (nth 2 oper))))
79 (nth 2 oper))
80 (if nest
81 (cons (if rev
82 (if accum 'calcFunc-afixp 'calcFunc-fixp)
83 (if accum 'calcFunc-anest 'calcFunc-nest))
84 (cons (math-calcFunc-to-var (nth 1 oper))
85 (calc-top-list-n
86 nargs (1+ calc-dollar-used))))
87 (list (if accum
88 (if rev 'calcFunc-raccum 'calcFunc-accum)
89 (intern (concat "calcFunc-"
90 (if rev "r" "")
91 "reduce"
92 calc-mapping-dir)))
93 (math-calcFunc-to-var (nth 1 oper))
94 (calc-top-n (1+ calc-dollar-used))))))))
95
96 (defun calc-accumulate (&optional oper)
97 (interactive)
98 (calc-reduce oper t))
99
100 (defun calc-map (&optional oper)
101 (interactive)
102 (calc-wrapper
103 (let* ((sel-mode nil)
104 (calc-dollar-values (mapcar 'calc-get-stack-element
105 (nthcdr calc-stack-top calc-stack)))
106 (calc-dollar-used 0)
107 (calc-mapping-dir "")
108 (oper (or oper (calc-get-operator "Map")))
109 (nargs (car oper)))
110 (message "Working...")
111 (calc-set-command-flag 'clear-message)
112 (calc-enter-result (+ nargs calc-dollar-used)
113 (concat (substring "map" 0 (- 4 (length (nth 2 oper))))
114 (nth 2 oper))
115 (cons (intern (concat "calcFunc-map" calc-mapping-dir))
116 (cons (math-calcFunc-to-var (nth 1 oper))
117 (calc-top-list-n
118 nargs
119 (1+ calc-dollar-used))))))))
120
121 (defun calc-map-equation (&optional oper)
122 (interactive)
123 (calc-wrapper
124 (let* ((sel-mode nil)
125 (calc-dollar-values (mapcar 'calc-get-stack-element
126 (nthcdr calc-stack-top calc-stack)))
127 (calc-dollar-used 0)
128 (oper (or oper (calc-get-operator "Map-equation")))
129 (nargs (car oper)))
130 (message "Working...")
131 (calc-set-command-flag 'clear-message)
132 (calc-enter-result (+ nargs calc-dollar-used)
133 (concat (substring "map" 0 (- 4 (length (nth 2 oper))))
134 (nth 2 oper))
135 (cons (if (calc-is-inverse)
136 'calcFunc-mapeqr
137 (if (calc-is-hyperbolic)
138 'calcFunc-mapeqp 'calcFunc-mapeq))
139 (cons (math-calcFunc-to-var (nth 1 oper))
140 (calc-top-list-n
141 nargs
142 (1+ calc-dollar-used))))))))
143
144 (defvar calc-verify-arglist t)
145 (defvar calc-mapping-dir nil)
146 (defun calc-map-stack ()
147 "This is meant to be called by calc-keypad mode."
148 (interactive)
149 (let ((calc-verify-arglist nil))
150 (calc-unread-command ?\$)
151 (calc-map)))
152
153 (defun calc-outer-product (&optional oper)
154 (interactive)
155 (calc-wrapper
156 (let* ((sel-mode nil)
157 (calc-dollar-values (mapcar 'calc-get-stack-element
158 (nthcdr calc-stack-top calc-stack)))
159 (calc-dollar-used 0)
160 (oper (or oper (calc-get-operator "Outer" 2))))
161 (message "Working...")
162 (calc-set-command-flag 'clear-message)
163 (calc-enter-result (+ 2 calc-dollar-used)
164 (concat (substring "out" 0 (- 4 (length (nth 2 oper))))
165 (nth 2 oper))
166 (cons 'calcFunc-outer
167 (cons (math-calcFunc-to-var (nth 1 oper))
168 (calc-top-list-n
169 2 (1+ calc-dollar-used))))))))
170
171 (defun calc-inner-product (&optional mul-oper add-oper)
172 (interactive)
173 (calc-wrapper
174 (let* ((sel-mode nil)
175 (calc-dollar-values (mapcar 'calc-get-stack-element
176 (nthcdr calc-stack-top calc-stack)))
177 (calc-dollar-used 0)
178 (mul-oper (or mul-oper (calc-get-operator "Inner (Mult)" 2)))
179 (mul-used calc-dollar-used)
180 (calc-dollar-values (if (> mul-used 0)
181 (cdr calc-dollar-values)
182 calc-dollar-values))
183 (calc-dollar-used 0)
184 (add-oper (or add-oper (calc-get-operator "Inner (Add)" 2))))
185 (message "Working...")
186 (calc-set-command-flag 'clear-message)
187 (calc-enter-result (+ 2 mul-used calc-dollar-used)
188 (concat "in"
189 (substring (nth 2 mul-oper) 0 1)
190 (substring (nth 2 add-oper) 0 1))
191 (nconc (list 'calcFunc-inner
192 (math-calcFunc-to-var (nth 1 mul-oper))
193 (math-calcFunc-to-var (nth 1 add-oper)))
194 (calc-top-list-n
195 2 (+ 1 mul-used calc-dollar-used)))))))
196
197 (defconst calc-oper-keys '( ( ( ?+ 2 calcFunc-add )
198 ( ?- 2 calcFunc-sub )
199 ( ?* 2 calcFunc-mul )
200 ( ?/ 2 calcFunc-div )
201 ( ?^ 2 calcFunc-pow )
202 ( ?| 2 calcFunc-vconcat )
203 ( ?% 2 calcFunc-mod )
204 ( ?\\ 2 calcFunc-idiv )
205 ( ?! 1 calcFunc-fact )
206 ( ?& 1 calcFunc-inv )
207 ( ?n 1 calcFunc-neg )
208 ( ?x user )
209 ( ?z user )
210 ( ?A 1 calcFunc-abs )
211 ( ?J 1 calcFunc-conj )
212 ( ?G 1 calcFunc-arg )
213 ( ?Q 1 calcFunc-sqrt )
214 ( ?N 2 calcFunc-min )
215 ( ?X 2 calcFunc-max )
216 ( ?F 1 calcFunc-floor )
217 ( ?R 1 calcFunc-round )
218 ( ?S 1 calcFunc-sin )
219 ( ?C 1 calcFunc-cos )
220 ( ?T 1 calcFunc-tan )
221 ( ?L 1 calcFunc-ln )
222 ( ?E 1 calcFunc-exp )
223 ( ?B 2 calcFunc-log ) )
224 ( ( ?F 1 calcFunc-ceil ) ; inverse
225 ( ?R 1 calcFunc-trunc )
226 ( ?Q 1 calcFunc-sqr )
227 ( ?S 1 calcFunc-arcsin )
228 ( ?C 1 calcFunc-arccos )
229 ( ?T 1 calcFunc-arctan )
230 ( ?L 1 calcFunc-exp )
231 ( ?E 1 calcFunc-ln )
232 ( ?B 2 calcFunc-alog )
233 ( ?^ 2 calcFunc-nroot )
234 ( ?| 2 calcFunc-vconcatrev ) )
235 ( ( ?F 1 calcFunc-ffloor ) ; hyperbolic
236 ( ?R 1 calcFunc-fround )
237 ( ?S 1 calcFunc-sinh )
238 ( ?C 1 calcFunc-cosh )
239 ( ?T 1 calcFunc-tanh )
240 ( ?L 1 calcFunc-log10 )
241 ( ?E 1 calcFunc-exp10 )
242 ( ?| 2 calcFunc-append ) )
243 ( ( ?F 1 calcFunc-fceil ) ; inverse-hyperbolic
244 ( ?R 1 calcFunc-ftrunc )
245 ( ?S 1 calcFunc-arcsinh )
246 ( ?C 1 calcFunc-arccosh )
247 ( ?T 1 calcFunc-arctanh )
248 ( ?L 1 calcFunc-exp10 )
249 ( ?E 1 calcFunc-log10 )
250 ( ?| 2 calcFunc-appendrev ) )))
251
252 (defconst calc-a-oper-keys '( ( ( ?a 3 calcFunc-apart )
253 ( ?b 3 calcFunc-subst )
254 ( ?c 2 calcFunc-collect )
255 ( ?d 2 calcFunc-deriv )
256 ( ?e 1 calcFunc-esimplify )
257 ( ?f 2 calcFunc-factor )
258 ( ?g 2 calcFunc-pgcd )
259 ( ?i 2 calcFunc-integ )
260 ( ?m 2 calcFunc-match )
261 ( ?n 1 calcFunc-nrat )
262 ( ?r 2 calcFunc-rewrite )
263 ( ?s 1 calcFunc-simplify )
264 ( ?t 3 calcFunc-taylor )
265 ( ?x 1 calcFunc-expand )
266 ( ?M 2 calcFunc-mapeq )
267 ( ?N 3 calcFunc-minimize )
268 ( ?P 2 calcFunc-roots )
269 ( ?R 3 calcFunc-root )
270 ( ?S 2 calcFunc-solve )
271 ( ?T 4 calcFunc-table )
272 ( ?X 3 calcFunc-maximize )
273 ( ?= 2 calcFunc-eq )
274 ( ?\# 2 calcFunc-neq )
275 ( ?< 2 calcFunc-lt )
276 ( ?> 2 calcFunc-gt )
277 ( ?\[ 2 calcFunc-leq )
278 ( ?\] 2 calcFunc-geq )
279 ( ?{ 2 calcFunc-in )
280 ( ?! 1 calcFunc-lnot )
281 ( ?& 2 calcFunc-land )
282 ( ?\| 2 calcFunc-lor )
283 ( ?: 3 calcFunc-if )
284 ( ?. 2 calcFunc-rmeq )
285 ( ?+ 4 calcFunc-sum )
286 ( ?- 4 calcFunc-asum )
287 ( ?* 4 calcFunc-prod )
288 ( ?_ 2 calcFunc-subscr )
289 ( ?\\ 2 calcFunc-pdiv )
290 ( ?% 2 calcFunc-prem )
291 ( ?/ 2 calcFunc-pdivrem ) )
292 ( ( ?m 2 calcFunc-matchnot )
293 ( ?M 2 calcFunc-mapeqr )
294 ( ?S 2 calcFunc-finv ) )
295 ( ( ?d 2 calcFunc-tderiv )
296 ( ?f 2 calcFunc-factors )
297 ( ?M 2 calcFunc-mapeqp )
298 ( ?N 3 calcFunc-wminimize )
299 ( ?R 3 calcFunc-wroot )
300 ( ?S 2 calcFunc-fsolve )
301 ( ?X 3 calcFunc-wmaximize )
302 ( ?/ 2 calcFunc-pdivide ) )
303 ( ( ?S 2 calcFunc-ffinv ) )))
304
305 (defconst calc-b-oper-keys '( ( ( ?a 2 calcFunc-and )
306 ( ?o 2 calcFunc-or )
307 ( ?x 2 calcFunc-xor )
308 ( ?d 2 calcFunc-diff )
309 ( ?n 1 calcFunc-not )
310 ( ?c 1 calcFunc-clip )
311 ( ?s 1 calcFunc-symclip )
312 ( ?l 2 calcFunc-lsh )
313 ( ?r 2 calcFunc-rsh )
314 ( ?L 2 calcFunc-ash )
315 ( ?R 2 calcFunc-rash )
316 ( ?t 2 calcFunc-rot )
317 ( ?p 1 calcFunc-vpack )
318 ( ?u 1 calcFunc-vunpack )
319 ( ?D 4 calcFunc-ddb )
320 ( ?F 3 calcFunc-fv )
321 ( ?I 1 calcFunc-irr )
322 ( ?M 3 calcFunc-pmt )
323 ( ?N 2 calcFunc-npv )
324 ( ?P 3 calcFunc-pv )
325 ( ?S 3 calcFunc-sln )
326 ( ?T 3 calcFunc-rate )
327 ( ?Y 4 calcFunc-syd )
328 ( ?\# 3 calcFunc-nper )
329 ( ?\% 2 calcFunc-relch ) )
330 ( ( ?F 3 calcFunc-fvb )
331 ( ?I 1 calcFunc-irrb )
332 ( ?M 3 calcFunc-pmtb )
333 ( ?N 2 calcFunc-npvb )
334 ( ?P 3 calcFunc-pvb )
335 ( ?T 3 calcFunc-rateb )
336 ( ?\# 3 calcFunc-nperb ) )
337 ( ( ?F 3 calcFunc-fvl )
338 ( ?M 3 calcFunc-pmtl )
339 ( ?P 3 calcFunc-pvl )
340 ( ?T 3 calcFunc-ratel )
341 ( ?\# 3 calcFunc-nperl ) )))
342
343 (defconst calc-c-oper-keys '( ( ( ?d 1 calcFunc-deg )
344 ( ?r 1 calcFunc-rad )
345 ( ?h 1 calcFunc-hms )
346 ( ?f 1 calcFunc-float )
347 ( ?F 1 calcFunc-frac ) )))
348
349 (defconst calc-f-oper-keys '( ( ( ?b 2 calcFunc-beta )
350 ( ?e 1 calcFunc-erf )
351 ( ?g 1 calcFunc-gamma )
352 ( ?h 2 calcFunc-hypot )
353 ( ?i 1 calcFunc-im )
354 ( ?j 2 calcFunc-besJ )
355 ( ?n 2 calcFunc-min )
356 ( ?r 1 calcFunc-re )
357 ( ?s 1 calcFunc-sign )
358 ( ?x 2 calcFunc-max )
359 ( ?y 2 calcFunc-besY )
360 ( ?A 1 calcFunc-abssqr )
361 ( ?B 3 calcFunc-betaI )
362 ( ?E 1 calcFunc-expm1 )
363 ( ?G 2 calcFunc-gammaP )
364 ( ?I 2 calcFunc-ilog )
365 ( ?L 1 calcFunc-lnp1 )
366 ( ?M 1 calcFunc-mant )
367 ( ?Q 1 calcFunc-isqrt )
368 ( ?S 1 calcFunc-scf )
369 ( ?T 2 calcFunc-arctan2 )
370 ( ?X 1 calcFunc-xpon )
371 ( ?\[ 2 calcFunc-decr )
372 ( ?\] 2 calcFunc-incr ) )
373 ( ( ?e 1 calcFunc-erfc )
374 ( ?E 1 calcFunc-lnp1 )
375 ( ?G 2 calcFunc-gammaQ )
376 ( ?L 1 calcFunc-expm1 ) )
377 ( ( ?B 3 calcFunc-betaB )
378 ( ?G 2 calcFunc-gammag) )
379 ( ( ?G 2 calcFunc-gammaG ) )))
380
381 (defconst calc-k-oper-keys '( ( ( ?b 1 calcFunc-bern )
382 ( ?c 2 calcFunc-choose )
383 ( ?d 1 calcFunc-dfact )
384 ( ?e 1 calcFunc-euler )
385 ( ?f 1 calcFunc-prfac )
386 ( ?g 2 calcFunc-gcd )
387 ( ?h 2 calcFunc-shuffle )
388 ( ?l 2 calcFunc-lcm )
389 ( ?m 1 calcFunc-moebius )
390 ( ?n 1 calcFunc-nextprime )
391 ( ?r 1 calcFunc-random )
392 ( ?s 2 calcFunc-stir1 )
393 ( ?t 1 calcFunc-totient )
394 ( ?B 3 calcFunc-utpb )
395 ( ?C 2 calcFunc-utpc )
396 ( ?F 3 calcFunc-utpf )
397 ( ?N 3 calcFunc-utpn )
398 ( ?P 2 calcFunc-utpp )
399 ( ?T 2 calcFunc-utpt ) )
400 ( ( ?n 1 calcFunc-prevprime )
401 ( ?B 3 calcFunc-ltpb )
402 ( ?C 2 calcFunc-ltpc )
403 ( ?F 3 calcFunc-ltpf )
404 ( ?N 3 calcFunc-ltpn )
405 ( ?P 2 calcFunc-ltpp )
406 ( ?T 2 calcFunc-ltpt ) )
407 ( ( ?b 2 calcFunc-bern )
408 ( ?c 2 calcFunc-perm )
409 ( ?e 2 calcFunc-euler )
410 ( ?s 2 calcFunc-stir2 ) )))
411
412 (defconst calc-s-oper-keys '( ( ( ?: 2 calcFunc-assign )
413 ( ?= 1 calcFunc-evalto ) )))
414
415 (defconst calc-t-oper-keys '( ( ( ?C 3 calcFunc-tzconv )
416 ( ?D 1 calcFunc-date )
417 ( ?I 2 calcFunc-incmonth )
418 ( ?J 1 calcFunc-julian )
419 ( ?M 1 calcFunc-newmonth )
420 ( ?W 1 calcFunc-newweek )
421 ( ?U 1 calcFunc-unixtime )
422 ( ?Y 1 calcFunc-newyear ) )))
423
424 (defconst calc-u-oper-keys '( ( ( ?C 2 calcFunc-vcov )
425 ( ?G 1 calcFunc-vgmean )
426 ( ?M 1 calcFunc-vmean )
427 ( ?N 1 calcFunc-vmin )
428 ( ?S 1 calcFunc-vsdev )
429 ( ?X 1 calcFunc-vmax ) )
430 ( ( ?C 2 calcFunc-vpcov )
431 ( ?M 1 calcFunc-vmeane )
432 ( ?S 1 calcFunc-vpsdev ) )
433 ( ( ?C 2 calcFunc-vcorr )
434 ( ?G 1 calcFunc-agmean )
435 ( ?M 1 calcFunc-vmedian )
436 ( ?S 1 calcFunc-vvar ) )
437 ( ( ?M 1 calcFunc-vhmean )
438 ( ?S 1 calcFunc-vpvar ) )))
439
440 (defconst calc-v-oper-keys '( ( ( ?a 2 calcFunc-arrange )
441 ( ?b 2 calcFunc-cvec )
442 ( ?c 2 calcFunc-mcol )
443 ( ?d 2 calcFunc-diag )
444 ( ?e 2 calcFunc-vexp )
445 ( ?f 2 calcFunc-find )
446 ( ?h 1 calcFunc-head )
447 ( ?k 2 calcFunc-cons )
448 ( ?l 1 calcFunc-vlen )
449 ( ?m 2 calcFunc-vmask )
450 ( ?n 1 calcFunc-rnorm )
451 ( ?p 2 calcFunc-pack )
452 ( ?r 2 calcFunc-mrow )
453 ( ?s 3 calcFunc-subvec )
454 ( ?t 1 calcFunc-trn )
455 ( ?u 1 calcFunc-unpack )
456 ( ?v 1 calcFunc-rev )
457 ( ?x 1 calcFunc-index )
458 ( ?A 1 calcFunc-apply )
459 ( ?C 1 calcFunc-cross )
460 ( ?D 1 calcFunc-det )
461 ( ?E 1 calcFunc-venum )
462 ( ?F 1 calcFunc-vfloor )
463 ( ?G 1 calcFunc-grade )
464 ( ?H 2 calcFunc-histogram )
465 ( ?I 2 calcFunc-inner )
466 ( ?L 1 calcFunc-lud )
467 ( ?M 0 calcFunc-map )
468 ( ?N 1 calcFunc-cnorm )
469 ( ?O 2 calcFunc-outer )
470 ( ?R 1 calcFunc-reduce )
471 ( ?S 1 calcFunc-sort )
472 ( ?T 1 calcFunc-tr )
473 ( ?U 1 calcFunc-accum )
474 ( ?V 2 calcFunc-vunion )
475 ( ?X 2 calcFunc-vxor )
476 ( ?- 2 calcFunc-vdiff )
477 ( ?^ 2 calcFunc-vint )
478 ( ?~ 1 calcFunc-vcompl )
479 ( ?# 1 calcFunc-vcard )
480 ( ?: 1 calcFunc-vspan )
481 ( ?+ 1 calcFunc-rdup ) )
482 ( ( ?h 1 calcFunc-tail )
483 ( ?s 3 calcFunc-rsubvec )
484 ( ?G 1 calcFunc-rgrade )
485 ( ?R 1 calcFunc-rreduce )
486 ( ?S 1 calcFunc-rsort )
487 ( ?U 1 calcFunc-raccum ) )
488 ( ( ?e 3 calcFunc-vexp )
489 ( ?h 1 calcFunc-rhead )
490 ( ?k 2 calcFunc-rcons )
491 ( ?H 3 calcFunc-histogram )
492 ( ?R 2 calcFunc-nest )
493 ( ?U 2 calcFunc-anest ) )
494 ( ( ?h 1 calcFunc-rtail )
495 ( ?R 1 calcFunc-fixp )
496 ( ?U 1 calcFunc-afixp ) )))
497
498
499 ;;; Return a list of the form (nargs func name)
500 (defvar calc-get-operator-history nil
501 "History for calc-get-operator.")
502
503 (defun calc-get-operator (msg &optional nargs)
504 (setq calc-aborted-prefix nil)
505 (let ((inv nil) (hyp nil) (prefix nil) (forcenargs nil)
506 done key oper (which 0)
507 (msgs '( "(Press ? for help)"
508 "+, -, *, /, ^, %, \\, :, &, !, |, Neg"
509 "SHIFT + Abs, conJ, arG; maX, miN; Floor, Round; sQrt"
510 "SHIFT + Inv, Hyp; Sin, Cos, Tan; Exp, Ln, logB"
511 "Algebra + Simp, Esimp, Deriv, Integ, !, =, etc."
512 "Binary + And, Or, Xor, Diff; l/r/t/L/R shifts; Not, Clip, Symclip"
513 "Conversions + Deg, Rad, HMS; Float; SHIFT + Fraction"
514 "Functions + Re, Im; Hypot; Mant, Expon, Scale; etc."
515 "Kombinatorics + Dfact, Lcm, Gcd, Choose; Random; etc."
516 "Time/date + newYear, Incmonth, etc."
517 "Vectors + Length, Row, Col, Diag, Mask, etc."
518 "_ = mapr/reducea, : = mapc/reduced, = = reducer"
519 "X or Z = any function by name; ' = alg entry; $ = stack")))
520 (while (not done)
521 (message "%s%s: %s: %s%s%s"
522 msg
523 (cond ((equal calc-mapping-dir "r") " rows")
524 ((equal calc-mapping-dir "c") " columns")
525 ((equal calc-mapping-dir "a") " across")
526 ((equal calc-mapping-dir "d") " down")
527 (t ""))
528 (if forcenargs
529 (format "(%d arg%s)"
530 forcenargs (if (= forcenargs 1) "" "s"))
531 (nth which msgs))
532 (if inv "Inv " "") (if hyp "Hyp " "")
533 (if prefix (concat (char-to-string prefix) "-") ""))
534 (setq key (read-char))
535 (if (>= key 128) (setq key (- key 128)))
536 (cond ((memq key '(?\C-g ?q))
537 (keyboard-quit))
538 ((memq key '(?\C-u ?\e)))
539 ((= key ??)
540 (setq which (% (1+ which) (length msgs))))
541 ((and (= key ?I) (null prefix))
542 (setq inv (not inv)))
543 ((and (= key ?H) (null prefix))
544 (setq hyp (not hyp)))
545 ((and (eq key prefix) (not (eq key ?v)))
546 (setq prefix nil))
547 ((and (memq key '(?a ?b ?c ?f ?k ?s ?t ?u ?v ?V))
548 (null prefix))
549 (setq prefix (downcase key)))
550 ((and (eq key ?\=) (null prefix))
551 (if calc-mapping-dir
552 (setq calc-mapping-dir (if (equal calc-mapping-dir "r")
553 "" "r"))
554 (beep)))
555 ((and (eq key ?\_) (null prefix))
556 (if calc-mapping-dir
557 (if (string-match "map$" msg)
558 (setq calc-mapping-dir (if (equal calc-mapping-dir "r")
559 "" "r"))
560 (setq calc-mapping-dir (if (equal calc-mapping-dir "a")
561 "" "a")))
562 (beep)))
563 ((and (eq key ?\:) (null prefix))
564 (if calc-mapping-dir
565 (if (string-match "map$" msg)
566 (setq calc-mapping-dir (if (equal calc-mapping-dir "c")
567 "" "c"))
568 (setq calc-mapping-dir (if (equal calc-mapping-dir "d")
569 "" "d")))
570 (beep)))
571 ((and (>= key ?0) (<= key ?9) (null prefix))
572 (setq forcenargs (if (eq forcenargs (- key ?0)) nil (- key ?0)))
573 (and nargs forcenargs (/= nargs forcenargs) (>= nargs 0)
574 (error "Must be a %d-argument operator" nargs)))
575 ((memq key '(?\$ ?\'))
576 (let* ((arglist nil)
577 (has-args nil)
578 (record-entry nil)
579 (expr (if (eq key ?\$)
580 (progn
581 (setq calc-dollar-used 1)
582 (if calc-dollar-values
583 (car calc-dollar-values)
584 (error "Stack underflow")))
585 (let* ((calc-dollar-values calc-arg-values)
586 (calc-dollar-used 0)
587 (calc-hashes-used 0)
588 (func (calc-do-alg-entry "" "Function: " nil
589 'calc-get-operator-history)))
590 (setq record-entry t)
591 (or (= (length func) 1)
592 (error "Bad format"))
593 (if (> calc-dollar-used 0)
594 (progn
595 (setq has-args calc-dollar-used
596 arglist (calc-invent-args has-args))
597 (math-multi-subst (car func)
598 (reverse arglist)
599 arglist))
600 (if (> calc-hashes-used 0)
601 (setq has-args calc-hashes-used
602 arglist (calc-invent-args has-args)))
603 (car func))))))
604 (if (eq (car-safe expr) 'calcFunc-lambda)
605 (setq oper (list "$" (- (length expr) 2) expr)
606 done t)
607 (or has-args
608 (progn
609 (calc-default-formula-arglist expr)
610 (setq record-entry t
611 arglist (sort arglist 'string-lessp))
612 (if calc-verify-arglist
613 (setq arglist (read-from-minibuffer
614 "Function argument list: "
615 (if arglist
616 (prin1-to-string arglist)
617 "()")
618 minibuffer-local-map
619 t)))
620 (setq arglist (mapcar (function
621 (lambda (x)
622 (list 'var
623 x
624 (intern
625 (concat
626 "var-"
627 (symbol-name x))))))
628 arglist))))
629 (setq oper (list "$"
630 (length arglist)
631 (append '(calcFunc-lambda) arglist
632 (list expr)))
633 done t))
634 (if record-entry
635 (calc-record (nth 2 oper) "oper"))))
636 ((setq oper (assq key (nth (if inv (if hyp 3 1) (if hyp 2 0))
637 (if prefix
638 (symbol-value
639 (intern (format "calc-%c-oper-keys"
640 prefix)))
641 calc-oper-keys))))
642 (if (eq (nth 1 oper) 'user)
643 (let ((func (intern
644 (completing-read "Function name: "
645 obarray 'fboundp
646 nil "calcFunc-"))))
647 (if (or forcenargs nargs)
648 (setq oper (list "z" (or forcenargs nargs) func)
649 done t)
650 (if (fboundp func)
651 (let* ((defn (symbol-function func)))
652 (and (symbolp defn)
653 (setq defn (symbol-function defn)))
654 (if (eq (car-safe defn) 'lambda)
655 (let ((args (nth 1 defn))
656 (nargs 0))
657 (while (not (memq (car args) '(&optional
658 &rest nil)))
659 (setq nargs (1+ nargs)
660 args (cdr args)))
661 (setq oper (list "z" nargs func)
662 done t))
663 (error
664 "Function is not suitable for this operation")))
665 (message "Number of arguments: ")
666 (let ((nargs (read-char)))
667 (if (and (>= nargs ?0) (<= nargs ?9))
668 (setq oper (list "z" (- nargs ?0) func)
669 done t)
670 (beep))))))
671 (if (or (and (eq prefix ?v) (memq key '(?A ?I ?M ?O ?R ?U)))
672 (and (eq prefix ?a) (eq key ?M)))
673 (let* ((dir (cond ((and (equal calc-mapping-dir "")
674 (string-match "map$" msg))
675 (setq calc-mapping-dir "r")
676 " rows")
677 ((equal calc-mapping-dir "r") " rows")
678 ((equal calc-mapping-dir "c") " columns")
679 ((equal calc-mapping-dir "a") " across")
680 ((equal calc-mapping-dir "d") " down")
681 (t "")))
682 (calc-mapping-dir (and (memq (nth 2 oper)
683 '(calcFunc-map
684 calcFunc-reduce
685 calcFunc-rreduce))
686 ""))
687 (oper2 (calc-get-operator
688 (format "%s%s, %s%s" msg dir
689 (substring (symbol-name (nth 2 oper))
690 9)
691 (if (eq key ?I) " (mult)" ""))
692 (cdr (assq (nth 2 oper)
693 '((calcFunc-reduce . 2)
694 (calcFunc-rreduce . 2)
695 (calcFunc-accum . 2)
696 (calcFunc-raccum . 2)
697 (calcFunc-nest . 2)
698 (calcFunc-anest . 2)
699 (calcFunc-fixp . 2)
700 (calcFunc-afixp . 2))))))
701 (oper3 (if (eq (nth 2 oper) 'calcFunc-inner)
702 (calc-get-operator
703 (format "%s%s, inner (add)" msg dir))
704 '(0 0 0)))
705 (args nil)
706 (nargs (if (> (nth 1 oper) 0)
707 (nth 1 oper)
708 (car oper2)))
709 (n nargs)
710 (p calc-arg-values))
711 (while (and p (> n 0))
712 (or (math-expr-contains (nth 1 oper2) (car p))
713 (math-expr-contains (nth 1 oper3) (car p))
714 (setq args (nconc args (list (car p)))
715 n (1- n)))
716 (setq p (cdr p)))
717 (setq oper (list "" nargs
718 (append
719 '(calcFunc-lambda)
720 args
721 (list (math-build-call
722 (intern
723 (concat
724 (symbol-name (nth 2 oper))
725 calc-mapping-dir))
726 (cons (math-calcFunc-to-var
727 (nth 1 oper2))
728 (if (eq key ?I)
729 (cons
730 (math-calcFunc-to-var
731 (nth 1 oper3))
732 args)
733 args))))))
734 done t))
735 (setq done t))))
736 (t (beep))))
737 (and nargs (>= nargs 0)
738 (/= nargs (nth 1 oper))
739 (error "Must be a %d-argument operator" nargs))
740 (append (if forcenargs
741 (cons forcenargs (cdr (cdr oper)))
742 (cdr oper))
743 (list
744 (let ((name (concat (if inv "I" "") (if hyp "H" "")
745 (if prefix (char-to-string prefix) "")
746 (char-to-string key))))
747 (if (> (length name) 3)
748 (substring name 0 3)
749 name))))))
750
751
752 ;;; Convert a variable name (as a formula) into a like-looking function name.
753 (defun math-var-to-calcFunc (f)
754 (if (eq (car-safe f) 'var)
755 (if (fboundp (nth 2 f))
756 (nth 2 f)
757 (intern (concat "calcFunc-" (symbol-name (nth 1 f)))))
758 (if (memq (car-safe f) '(lambda calcFunc-lambda))
759 f
760 (math-reject-arg f "*Expected a function name"))))
761
762 ;;; Convert a function name into a like-looking variable name formula.
763 (defun math-calcFunc-to-var (f)
764 (if (symbolp f)
765 (let* ((func (or (cdr (assq f '( ( + . calcFunc-add )
766 ( - . calcFunc-sub )
767 ( * . calcFunc-mul )
768 ( / . calcFunc-div )
769 ( ^ . calcFunc-pow )
770 ( % . calcFunc-mod )
771 ( neg . calcFunc-neg )
772 ( | . calcFunc-vconcat ) )))
773 f))
774 (base (if (string-match "\\`calcFunc-\\(.+\\)\\'"
775 (symbol-name func))
776 (math-match-substring (symbol-name func) 1)
777 (symbol-name func))))
778 (list 'var
779 (intern base)
780 (intern (concat "var-" base))))
781 f))
782
783 ;;; Expand a function call using "lambda" notation.
784 (defun math-build-call (f args)
785 (if (eq (car-safe f) 'calcFunc-lambda)
786 (if (= (length args) (- (length f) 2))
787 (math-multi-subst (nth (1- (length f)) f) (cdr f) args)
788 (calc-record-why "*Wrong number of arguments" f)
789 (cons 'calcFunc-call (cons (math-calcFunc-to-var f) args)))
790 (if (and (eq f 'calcFunc-neg)
791 (= (length args) 1))
792 (list 'neg (car args))
793 (let ((func (assq f '( ( calcFunc-add . + )
794 ( calcFunc-sub . - )
795 ( calcFunc-mul . * )
796 ( calcFunc-div . / )
797 ( calcFunc-pow . ^ )
798 ( calcFunc-mod . % )
799 ( calcFunc-vconcat . | ) ))))
800 (if (and func (= (length args) 2))
801 (cons (cdr func) args)
802 (cons f args))))))
803
804 ;;; Do substitutions in parallel to avoid crosstalk.
805
806 ;; The variables math-ms-temp and math-ms-args are local to
807 ;; math-multi-subst, but are used by math-multi-subst-rec, which
808 ;; is called by math-multi-subst.
809 (defvar math-ms-temp)
810 (defvar math-ms-args)
811
812 (defun math-multi-subst (expr olds news)
813 (let ((math-ms-args nil)
814 math-ms-temp)
815 (while (and olds news)
816 (setq math-ms-args (cons (cons (car olds) (car news)) math-ms-args)
817 olds (cdr olds)
818 news (cdr news)))
819 (math-multi-subst-rec expr)))
820
821 (defun math-multi-subst-rec (expr)
822 (cond ((setq math-ms-temp (assoc expr math-ms-args))
823 (cdr math-ms-temp))
824 ((Math-primp expr) expr)
825 ((and (eq (car expr) 'calcFunc-lambda) (> (length expr) 2))
826 (let ((new (list (car expr)))
827 (math-ms-args math-ms-args))
828 (while (cdr (setq expr (cdr expr)))
829 (setq new (cons (car expr) new))
830 (if (assoc (car expr) math-ms-args)
831 (setq math-ms-args (cons (cons (car expr) (car expr))
832 math-ms-args))))
833 (nreverse (cons (math-multi-subst-rec (car expr)) new))))
834 (t
835 (cons (car expr)
836 (mapcar 'math-multi-subst-rec (cdr expr))))))
837
838 (defun calcFunc-call (f &rest args)
839 (setq args (math-build-call (math-var-to-calcFunc f) args))
840 (if (eq (car-safe args) 'calcFunc-call)
841 args
842 (math-normalize args)))
843
844 (defun calcFunc-apply (f args)
845 (or (Math-vectorp args)
846 (math-reject-arg args 'vectorp))
847 (apply 'calcFunc-call (cons f (cdr args))))
848
849
850
851
852 ;;; Map a function over a vector symbolically. [Public]
853 (defun math-symb-map (f mode args)
854 (let* ((func (math-var-to-calcFunc f))
855 (nargs (length args))
856 (ptrs (vconcat args))
857 (vflags (make-vector nargs nil))
858 (heads '(vec))
859 (head nil)
860 (vec nil)
861 (i -1)
862 (math-working-step 0)
863 (math-working-step-2 nil)
864 len cols obj expr)
865 (if (eq mode 'eqn)
866 (setq mode 'elems
867 heads '(calcFunc-eq calcFunc-neq calcFunc-lt calcFunc-gt
868 calcFunc-leq calcFunc-geq))
869 (while (and (< (setq i (1+ i)) nargs)
870 (not (math-matrixp (aref ptrs i)))))
871 (if (< i nargs)
872 (if (eq mode 'elems)
873 (setq func (list 'lambda '(&rest x)
874 (list 'math-symb-map
875 (list 'quote f) '(quote elems) 'x))
876 mode 'rows)
877 (if (eq mode 'cols)
878 (while (< i nargs)
879 (if (math-matrixp (aref ptrs i))
880 (aset ptrs i (math-transpose (aref ptrs i))))
881 (setq i (1+ i)))))
882 (setq mode 'elems))
883 (setq i -1))
884 (while (< (setq i (1+ i)) nargs)
885 (setq obj (aref ptrs i))
886 (if (and (memq (car-safe obj) heads)
887 (or (eq mode 'elems)
888 (math-matrixp obj)))
889 (progn
890 (aset vflags i t)
891 (if head
892 (if (cdr heads)
893 (setq head (nth
894 (aref (aref [ [0 1 2 3 4 5]
895 [1 1 2 3 2 3]
896 [2 2 2 1 2 1]
897 [3 3 1 3 1 3]
898 [4 2 2 1 4 1]
899 [5 3 1 3 1 5] ]
900 (- 6 (length (memq head heads))))
901 (- 6 (length (memq (car obj) heads))))
902 heads)))
903 (setq head (car obj)))
904 (if len
905 (or (= (length obj) len)
906 (math-dimension-error))
907 (setq len (length obj))))))
908 (or len
909 (if (= nargs 1)
910 (math-reject-arg (aref ptrs 0) 'vectorp)
911 (math-reject-arg nil "At least one argument must be a vector")))
912 (setq math-working-step-2 (1- len))
913 (while (> (setq len (1- len)) 0)
914 (setq expr nil
915 i -1)
916 (while (< (setq i (1+ i)) nargs)
917 (if (aref vflags i)
918 (progn
919 (aset ptrs i (cdr (aref ptrs i)))
920 (setq expr (nconc expr (list (car (aref ptrs i))))))
921 (setq expr (nconc expr (list (aref ptrs i))))))
922 (setq math-working-step (1+ math-working-step)
923 vec (cons (math-normalize (math-build-call func expr)) vec)))
924 (setq vec (cons head (nreverse vec)))
925 (if (and (eq mode 'cols) (math-matrixp vec))
926 (math-transpose vec)
927 vec)))
928
929 (defun calcFunc-map (func &rest args)
930 (math-symb-map func 'elems args))
931
932 (defun calcFunc-mapr (func &rest args)
933 (math-symb-map func 'rows args))
934
935 (defun calcFunc-mapc (func &rest args)
936 (math-symb-map func 'cols args))
937
938 (defun calcFunc-mapa (func arg)
939 (if (math-matrixp arg)
940 (math-symb-map func 'elems (cdr (math-transpose arg)))
941 (math-symb-map func 'elems arg)))
942
943 (defun calcFunc-mapd (func arg)
944 (if (math-matrixp arg)
945 (math-symb-map func 'elems (cdr arg))
946 (math-symb-map func 'elems arg)))
947
948 (defun calcFunc-mapeq (func &rest args)
949 (if (and (or (equal func '(var mul var-mul))
950 (equal func '(var div var-div)))
951 (= (length args) 2))
952 (if (math-negp (car args))
953 (let ((func (nth 1 (assq (car-safe (nth 1 args))
954 calc-tweak-eqn-table))))
955 (and func (setq args (list (car args)
956 (cons func (cdr (nth 1 args)))))))
957 (if (math-negp (nth 1 args))
958 (let ((func (nth 1 (assq (car-safe (car args))
959 calc-tweak-eqn-table))))
960 (and func (setq args (list (cons func (cdr (car args)))
961 (nth 1 args))))))))
962 (if (or (and (equal func '(var div var-div))
963 (assq (car-safe (nth 1 args)) calc-tweak-eqn-table))
964 (equal func '(var neg var-neg))
965 (equal func '(var inv var-inv)))
966 (apply 'calcFunc-mapeqr func args)
967 (apply 'calcFunc-mapeqp func args)))
968
969 (defun calcFunc-mapeqr (func &rest args)
970 (setq args (mapcar (function (lambda (x)
971 (let ((func (assq (car-safe x)
972 calc-tweak-eqn-table)))
973 (if func
974 (cons (nth 1 func) (cdr x))
975 x))))
976 args))
977 (apply 'calcFunc-mapeqp func args))
978
979 (defun calcFunc-mapeqp (func &rest args)
980 (if (or (and (memq (car-safe (car args)) '(calcFunc-lt calcFunc-leq))
981 (memq (car-safe (nth 1 args)) '(calcFunc-gt calcFunc-geq)))
982 (and (memq (car-safe (car args)) '(calcFunc-gt calcFunc-geq))
983 (memq (car-safe (nth 1 args)) '(calcFunc-lt calcFunc-leq))))
984 (setq args (cons (car args)
985 (cons (list (nth 1 (assq (car (nth 1 args))
986 calc-tweak-eqn-table))
987 (nth 2 (nth 1 args))
988 (nth 1 (nth 1 args)))
989 (cdr (cdr args))))))
990 (math-symb-map func 'eqn args))
991
992
993
994 ;;; Reduce a function over a vector symbolically. [Public]
995 (defun calcFunc-reduce (func vec)
996 (if (math-matrixp vec)
997 (let (expr row)
998 (setq func (math-var-to-calcFunc func))
999 (while (setq vec (cdr vec))
1000 (setq row (car vec))
1001 (while (setq row (cdr row))
1002 (setq expr (if expr
1003 (if (Math-numberp expr)
1004 (math-normalize
1005 (math-build-call func (list expr (car row))))
1006 (math-build-call func (list expr (car row))))
1007 (car row)))))
1008 (math-normalize expr))
1009 (calcFunc-reducer func vec)))
1010
1011 (defun calcFunc-rreduce (func vec)
1012 (if (math-matrixp vec)
1013 (let (expr row)
1014 (setq func (math-var-to-calcFunc func)
1015 vec (reverse (cdr vec)))
1016 (while vec
1017 (setq row (reverse (cdr (car vec))))
1018 (while row
1019 (setq expr (if expr
1020 (math-build-call func (list (car row) expr))
1021 (car row))
1022 row (cdr row)))
1023 (setq vec (cdr vec)))
1024 (math-normalize expr))
1025 (calcFunc-rreducer func vec)))
1026
1027 (defun calcFunc-reducer (func vec)
1028 (setq func (math-var-to-calcFunc func))
1029 (or (math-vectorp vec)
1030 (math-reject-arg vec 'vectorp))
1031 (let ((expr (car (setq vec (cdr vec)))))
1032 (if expr
1033 (progn
1034 (condition-case err
1035 (and (symbolp func)
1036 (let ((lfunc (or (cdr (assq func
1037 '( (calcFunc-add . math-add)
1038 (calcFunc-sub . math-sub)
1039 (calcFunc-mul . math-mul)
1040 (calcFunc-div . math-div)
1041 (calcFunc-pow . math-pow)
1042 (calcFunc-mod . math-mod)
1043 (calcFunc-vconcat .
1044 math-concat) )))
1045 func)))
1046 (while (cdr vec)
1047 (setq expr (funcall lfunc expr (nth 1 vec))
1048 vec (cdr vec)))))
1049 (error nil))
1050 (while (setq vec (cdr vec))
1051 (setq expr (math-build-call func (list expr (car vec)))))
1052 (math-normalize expr))
1053 (or (math-identity-value func)
1054 (math-reject-arg vec "*Vector is empty")))))
1055
1056 (defun math-identity-value (func)
1057 (cdr (assq func '( (calcFunc-add . 0) (calcFunc-sub . 0)
1058 (calcFunc-mul . 1) (calcFunc-div . 1)
1059 (calcFunc-idiv . 1) (calcFunc-fdiv . 1)
1060 (calcFunc-min . (var inf var-inf))
1061 (calcFunc-max . (neg (var inf var-inf)))
1062 (calcFunc-vconcat . (vec))
1063 (calcFunc-append . (vec)) ))))
1064
1065 (defun calcFunc-rreducer (func vec)
1066 (setq func (math-var-to-calcFunc func))
1067 (or (math-vectorp vec)
1068 (math-reject-arg vec 'vectorp))
1069 (if (eq func 'calcFunc-sub) ; do this in a way that looks nicer
1070 (let ((expr (car (setq vec (cdr vec)))))
1071 (if expr
1072 (progn
1073 (while (setq vec (cdr vec))
1074 (setq expr (math-build-call func (list expr (car vec)))
1075 func (if (eq func 'calcFunc-sub)
1076 'calcFunc-add 'calcFunc-sub)))
1077 (math-normalize expr))
1078 0))
1079 (let ((expr (car (setq vec (reverse (cdr vec))))))
1080 (if expr
1081 (progn
1082 (while (setq vec (cdr vec))
1083 (setq expr (math-build-call func (list (car vec) expr))))
1084 (math-normalize expr))
1085 (or (math-identity-value func)
1086 (math-reject-arg vec "*Vector is empty"))))))
1087
1088 (defun calcFunc-reducec (func vec)
1089 (if (math-matrixp vec)
1090 (calcFunc-reducer func (math-transpose vec))
1091 (calcFunc-reducer func vec)))
1092
1093 (defun calcFunc-rreducec (func vec)
1094 (if (math-matrixp vec)
1095 (calcFunc-rreducer func (math-transpose vec))
1096 (calcFunc-rreducer func vec)))
1097
1098 (defun calcFunc-reducea (func vec)
1099 (if (math-matrixp vec)
1100 (cons 'vec
1101 (mapcar (function (lambda (x) (calcFunc-reducer func x)))
1102 (cdr vec)))
1103 (calcFunc-reducer func vec)))
1104
1105 (defun calcFunc-rreducea (func vec)
1106 (if (math-matrixp vec)
1107 (cons 'vec
1108 (mapcar (function (lambda (x) (calcFunc-rreducer func x)))
1109 (cdr vec)))
1110 (calcFunc-rreducer func vec)))
1111
1112 (defun calcFunc-reduced (func vec)
1113 (if (math-matrixp vec)
1114 (cons 'vec
1115 (mapcar (function (lambda (x) (calcFunc-reducer func x)))
1116 (cdr (math-transpose vec))))
1117 (calcFunc-reducer func vec)))
1118
1119 (defun calcFunc-rreduced (func vec)
1120 (if (math-matrixp vec)
1121 (cons 'vec
1122 (mapcar (function (lambda (x) (calcFunc-rreducer func x)))
1123 (cdr (math-transpose vec))))
1124 (calcFunc-rreducer func vec)))
1125
1126 (defun calcFunc-accum (func vec)
1127 (setq func (math-var-to-calcFunc func))
1128 (or (math-vectorp vec)
1129 (math-reject-arg vec 'vectorp))
1130 (let* ((expr (car (setq vec (cdr vec))))
1131 (res (list 'vec expr)))
1132 (or expr
1133 (math-reject-arg vec "*Vector is empty"))
1134 (while (setq vec (cdr vec))
1135 (setq expr (math-build-call func (list expr (car vec)))
1136 res (nconc res (list expr))))
1137 (math-normalize res)))
1138
1139 (defun calcFunc-raccum (func vec)
1140 (setq func (math-var-to-calcFunc func))
1141 (or (math-vectorp vec)
1142 (math-reject-arg vec 'vectorp))
1143 (let* ((expr (car (setq vec (reverse (cdr vec)))))
1144 (res (list expr)))
1145 (or expr
1146 (math-reject-arg vec "*Vector is empty"))
1147 (while (setq vec (cdr vec))
1148 (setq expr (math-build-call func (list (car vec) expr))
1149 res (cons (list expr) res)))
1150 (math-normalize (cons 'vec res))))
1151
1152
1153 (defun math-nest-calls (func base iters accum tol)
1154 (or (symbolp tol)
1155 (if (math-realp tol)
1156 (or (math-numberp base) (math-reject-arg base 'numberp))
1157 (math-reject-arg tol 'realp)))
1158 (setq func (math-var-to-calcFunc func))
1159 (or (null iters)
1160 (if (equal iters '(var inf var-inf))
1161 (setq iters nil)
1162 (progn
1163 (if (math-messy-integerp iters)
1164 (setq iters (math-trunc iters)))
1165 (or (integerp iters) (math-reject-arg iters 'fixnump))
1166 (or (not tol) (natnump iters) (math-reject-arg iters 'fixnatnump))
1167 (if (< iters 0)
1168 (let* ((dummy '(var DummyArg var-DummyArg))
1169 (dummy2 '(var DummyArg2 var-DummyArg2))
1170 (finv (math-solve-for (math-build-call func (list dummy2))
1171 dummy dummy2 nil)))
1172 (or finv (math-reject-arg nil "*Unable to find an inverse"))
1173 (if (and (= (length finv) 2)
1174 (equal (nth 1 finv) dummy))
1175 (setq func (car finv))
1176 (setq func (list 'calcFunc-lambda dummy finv)))
1177 (setq iters (- iters)))))))
1178 (math-with-extra-prec 1
1179 (let ((value base)
1180 (ovalue nil)
1181 (avalues (list base))
1182 (math-working-step 0)
1183 (math-working-step-2 iters))
1184 (while (and (or (null iters)
1185 (>= (setq iters (1- iters)) 0))
1186 (or (null tol)
1187 (null ovalue)
1188 (if (eq tol t)
1189 (not (if (and (Math-numberp value)
1190 (Math-numberp ovalue))
1191 (math-nearly-equal value ovalue)
1192 (Math-equal value ovalue)))
1193 (if (math-numberp value)
1194 (Math-lessp tol (math-abs (math-sub value ovalue)))
1195 (math-reject-arg value 'numberp)))))
1196 (setq ovalue value
1197 math-working-step (1+ math-working-step)
1198 value (math-normalize (math-build-call func (list value))))
1199 (if accum
1200 (setq avalues (cons value avalues))))
1201 (if accum
1202 (cons 'vec (nreverse avalues))
1203 value))))
1204
1205 (defun calcFunc-nest (func base iters)
1206 (math-nest-calls func base iters nil nil))
1207
1208 (defun calcFunc-anest (func base iters)
1209 (math-nest-calls func base iters t nil))
1210
1211 (defun calcFunc-fixp (func base &optional iters tol)
1212 (math-nest-calls func base iters nil (or tol t)))
1213
1214 (defun calcFunc-afixp (func base &optional iters tol)
1215 (math-nest-calls func base iters t (or tol t)))
1216
1217
1218 (defun calcFunc-outer (func a b)
1219 (or (math-vectorp a) (math-reject-arg a 'vectorp))
1220 (or (math-vectorp b) (math-reject-arg b 'vectorp))
1221 (setq func (math-var-to-calcFunc func))
1222 (let ((mat nil))
1223 (while (setq a (cdr a))
1224 (setq mat (cons (cons 'vec
1225 (mapcar (function (lambda (x)
1226 (math-build-call func
1227 (list (car a)
1228 x))))
1229 (cdr b)))
1230 mat)))
1231 (math-normalize (cons 'vec (nreverse mat)))))
1232
1233
1234 ;; The variables math-inner-mul-func and math-inner-add-func are
1235 ;; local to calcFunc-inner, but are used by math-inner-mats,
1236 ;; which is called by math-inner-mats.
1237 (defvar math-inner-mul-func)
1238 (defvar math-inner-add-func)
1239
1240 (defun calcFunc-inner (math-inner-mul-func math-inner-add-func a b)
1241 (or (math-vectorp a) (math-reject-arg a 'vectorp))
1242 (or (math-vectorp b) (math-reject-arg b 'vectorp))
1243 (if (math-matrixp a)
1244 (if (math-matrixp b)
1245 (if (= (length (nth 1 a)) (length b))
1246 (math-inner-mats a b)
1247 (math-dimension-error))
1248 (if (= (length (nth 1 a)) 2)
1249 (if (= (length a) (length b))
1250 (math-inner-mats a (list 'vec b))
1251 (math-dimension-error))
1252 (if (= (length (nth 1 a)) (length b))
1253 (math-mat-col (math-inner-mats a (math-col-matrix b))
1254 1)
1255 (math-dimension-error))))
1256 (if (math-matrixp b)
1257 (nth 1 (math-inner-mats (list 'vec a) b))
1258 (calcFunc-reduce math-inner-add-func (calcFunc-map math-inner-mul-func a b)))))
1259
1260 (defun math-inner-mats (a b)
1261 (let ((mat nil)
1262 (cols (length (nth 1 b)))
1263 row col ap bp accum)
1264 (while (setq a (cdr a))
1265 (setq col cols
1266 row nil)
1267 (while (> (setq col (1- col)) 0)
1268 (setq row (cons (calcFunc-reduce math-inner-add-func
1269 (calcFunc-map math-inner-mul-func
1270 (car a)
1271 (math-mat-col b col)))
1272 row)))
1273 (setq mat (cons (cons 'vec row) mat)))
1274 (cons 'vec (nreverse mat))))
1275
1276 (provide 'calc-map)
1277
1278 ;; arch-tag: 980eac49-00e0-4870-b72a-e726b74c7990
1279 ;;; calc-map.el ends here