calc-map.el 40 KB

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