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