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