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