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