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