ramap.c 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032
  1. /* Copyright (C) 1996, 1998, 2000, 2002 Free Software Foundation, Inc.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2, or (at your option)
  6. * any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; see the file COPYING. If not, write to
  15. * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  16. * Boston, MA 02111-1307 USA
  17. *
  18. * As a special exception, the Free Software Foundation gives permission
  19. * for additional uses of the text contained in its release of GUILE.
  20. *
  21. * The exception is that, if you link the GUILE library with other files
  22. * to produce an executable, this does not by itself cause the
  23. * resulting executable to be covered by the GNU General Public License.
  24. * Your use of that executable is in no way restricted on account of
  25. * linking the GUILE library code into it.
  26. *
  27. * This exception does not however invalidate any other reasons why
  28. * the executable file might be covered by the GNU General Public License.
  29. *
  30. * This exception applies only to the code released by the
  31. * Free Software Foundation under the name GUILE. If you copy
  32. * code from other Free Software Foundation releases into a copy of
  33. * GUILE, as the General Public License permits, the exception does
  34. * not apply to the code that you add in this way. To avoid misleading
  35. * anyone as to the status of such modified files, you must delete
  36. * this exception notice from them.
  37. *
  38. * If you write modifications of your own for GUILE, it is your choice
  39. * whether to permit this exception to apply to your modifications.
  40. * If you do not wish that, delete this exception notice. */
  41. /*
  42. HWN:FIXME::
  43. Someone should rename this to arraymap.c; that would reflect the
  44. contents better. */
  45. #include <stdio.h>
  46. #include "libguile/_scm.h"
  47. #include "libguile/unif.h"
  48. #include "libguile/smob.h"
  49. #include "libguile/chars.h"
  50. #include "libguile/eq.h"
  51. #include "libguile/eval.h"
  52. #include "libguile/feature.h"
  53. #include "libguile/root.h"
  54. #include "libguile/vectors.h"
  55. #include "libguile/validate.h"
  56. #include "libguile/ramap.h"
  57. typedef struct
  58. {
  59. char *name;
  60. SCM sproc;
  61. int (*vproc) ();
  62. } ra_iproc;
  63. /* These tables are a kluge that will not scale well when more
  64. * vectorized subrs are added. It is tempting to steal some bits from
  65. * the SCM_CAR of all subrs (like those selected by SCM_SMOBNUM) to hold an
  66. * offset into a table of vectorized subrs.
  67. */
  68. static ra_iproc ra_rpsubrs[] =
  69. {
  70. {"=", SCM_UNDEFINED, scm_ra_eqp},
  71. {"<", SCM_UNDEFINED, scm_ra_lessp},
  72. {"<=", SCM_UNDEFINED, scm_ra_leqp},
  73. {">", SCM_UNDEFINED, scm_ra_grp},
  74. {">=", SCM_UNDEFINED, scm_ra_greqp},
  75. {0, 0, 0}
  76. };
  77. static ra_iproc ra_asubrs[] =
  78. {
  79. {"+", SCM_UNDEFINED, scm_ra_sum},
  80. {"-", SCM_UNDEFINED, scm_ra_difference},
  81. {"*", SCM_UNDEFINED, scm_ra_product},
  82. {"/", SCM_UNDEFINED, scm_ra_divide},
  83. {0, 0, 0}
  84. };
  85. /* Fast, recycling scm_vector ref */
  86. #define RVREF(ra, i, e) (e = scm_cvref(ra, i, e))
  87. /* #define RVREF(ra, i, e) (scm_cvref(ra, i, SCM_UNDEFINED)) to turn off */
  88. /* IVDEP means "ignore scm_vector dependencies", meaning we guarantee that
  89. elements of scm_vector operands are not aliased */
  90. #ifdef _UNICOS
  91. #define IVDEP(test, line) if (test) {_Pragma("ivdep"); line} else {line}
  92. #else
  93. #define IVDEP(test, line) line
  94. #endif
  95. /* inds must be a uvect or ivect, no check. */
  96. /*
  97. Yes, this is really ugly, but it prevents multiple code
  98. */
  99. #define BINARY_ELTS_CODE(OPERATOR, type) \
  100. do { type *v0 = (type*)SCM_VELTS (ra0);\
  101. type *v1 = (type*)SCM_VELTS (ra1);\
  102. IVDEP (ra0 != ra1, \
  103. for (; n-- > 0; i0 += inc0, i1 += inc1) \
  104. v0[i0] OPERATOR v1[i1];) \
  105. break; \
  106. } while (0)
  107. /* This macro is used for all but binary division and
  108. multiplication of complex numbers -- see the expanded
  109. version in the functions later in this file */
  110. #define BINARY_PAIR_ELTS_CODE(OPERATOR, type) \
  111. do { type (*v0)[2] = (type (*)[2]) SCM_VELTS (ra0);\
  112. type (*v1)[2] = (type (*)[2]) SCM_VELTS (ra1);\
  113. IVDEP (ra0 != ra1, \
  114. for (; n-- > 0; i0 += inc0, i1 += inc1) {\
  115. v0[i0][0] OPERATOR v1[i1][0]; \
  116. v0[i0][1] OPERATOR v1[i1][1]; \
  117. }) \
  118. break; \
  119. } while (0)
  120. #define UNARY_ELTS_CODE(OPERATOR, type) \
  121. do { type *v0 = (type *) SCM_VELTS (ra0);\
  122. for (; n-- > 0; i0 += inc0) \
  123. v0[i0] OPERATOR v0[i0];\
  124. break;\
  125. } while (0)
  126. /* This macro is used for all but unary divison
  127. of complex numbers -- see the expanded version in the
  128. function later in this file. */
  129. #define UNARY_PAIR_ELTS_CODE(OPERATOR, type) \
  130. do { type (*v0)[2] = (type (*)[2]) SCM_VELTS (ra0);\
  131. for (; n-- > 0; i0 += inc0) {\
  132. v0[i0][0] OPERATOR v0[i0][0];\
  133. v0[i0][1] OPERATOR v0[i0][1];\
  134. }\
  135. break;\
  136. } while (0)
  137. static scm_sizet
  138. cind (SCM ra, SCM inds)
  139. {
  140. scm_sizet i;
  141. int k;
  142. long *ve = (long*) SCM_VELTS (inds);
  143. if (!SCM_ARRAYP (ra))
  144. return *ve;
  145. i = SCM_ARRAY_BASE (ra);
  146. for (k = 0; k < SCM_ARRAY_NDIM (ra); k++)
  147. i += (ve[k] - SCM_ARRAY_DIMS (ra)[k].lbnd) * SCM_ARRAY_DIMS (ra)[k].inc;
  148. return i;
  149. }
  150. /* Checker for scm_array mapping functions:
  151. return values: 4 --> shapes, increments, and bases are the same;
  152. 3 --> shapes and increments are the same;
  153. 2 --> shapes are the same;
  154. 1 --> ras are at least as big as ra0;
  155. 0 --> no match.
  156. */
  157. int
  158. scm_ra_matchp (SCM ra0, SCM ras)
  159. {
  160. SCM ra1;
  161. scm_array_dim dims;
  162. scm_array_dim *s0 = &dims;
  163. scm_array_dim *s1;
  164. scm_sizet bas0 = 0;
  165. int i, ndim = 1;
  166. int exact = 2 /* 4 */ ; /* Don't care about values >2 (yet?) */
  167. if (SCM_IMP (ra0)) return 0;
  168. switch (SCM_TYP7 (ra0))
  169. {
  170. default:
  171. return 0;
  172. case scm_tc7_vector:
  173. case scm_tc7_wvect:
  174. case scm_tc7_string:
  175. case scm_tc7_byvect:
  176. case scm_tc7_bvect:
  177. case scm_tc7_uvect:
  178. case scm_tc7_ivect:
  179. case scm_tc7_svect:
  180. #ifdef HAVE_LONG_LONGS
  181. case scm_tc7_llvect:
  182. #endif
  183. case scm_tc7_fvect:
  184. case scm_tc7_dvect:
  185. case scm_tc7_cvect:
  186. s0->lbnd = 0;
  187. s0->inc = 1;
  188. s0->ubnd = (long) SCM_LENGTH (ra0) - 1;
  189. break;
  190. case scm_tc7_smob:
  191. if (!SCM_ARRAYP (ra0))
  192. return 0;
  193. ndim = SCM_ARRAY_NDIM (ra0);
  194. s0 = SCM_ARRAY_DIMS (ra0);
  195. bas0 = SCM_ARRAY_BASE (ra0);
  196. break;
  197. }
  198. while (SCM_NIMP (ras))
  199. {
  200. ra1 = SCM_CAR (ras);
  201. if (SCM_IMP (ra1))
  202. return 0;
  203. switch SCM_TYP7
  204. (ra1)
  205. {
  206. default:
  207. return 0;
  208. case scm_tc7_vector:
  209. case scm_tc7_wvect:
  210. case scm_tc7_string:
  211. case scm_tc7_byvect:
  212. case scm_tc7_bvect:
  213. case scm_tc7_uvect:
  214. case scm_tc7_ivect:
  215. case scm_tc7_svect:
  216. #ifdef HAVE_LONG_LONGS
  217. case scm_tc7_llvect:
  218. #endif
  219. case scm_tc7_fvect:
  220. case scm_tc7_dvect:
  221. case scm_tc7_cvect:
  222. if (1 != ndim)
  223. return 0;
  224. switch (exact)
  225. {
  226. case 4:
  227. if (0 != bas0)
  228. exact = 3;
  229. case 3:
  230. if (1 != s0->inc)
  231. exact = 2;
  232. case 2:
  233. if ((0 == s0->lbnd) && (s0->ubnd == SCM_LENGTH (ra1) - 1))
  234. break;
  235. exact = 1;
  236. case 1:
  237. if (s0->lbnd < 0 || s0->ubnd >= SCM_LENGTH (ra1))
  238. return 0;
  239. }
  240. break;
  241. case scm_tc7_smob:
  242. if (!SCM_ARRAYP (ra1) || ndim != SCM_ARRAY_NDIM (ra1))
  243. return 0;
  244. s1 = SCM_ARRAY_DIMS (ra1);
  245. if (bas0 != SCM_ARRAY_BASE (ra1))
  246. exact = 3;
  247. for (i = 0; i < ndim; i++)
  248. switch (exact)
  249. {
  250. case 4:
  251. case 3:
  252. if (s0[i].inc != s1[i].inc)
  253. exact = 2;
  254. case 2:
  255. if (s0[i].lbnd == s1[i].lbnd && s0[i].ubnd == s1[i].ubnd)
  256. break;
  257. exact = 1;
  258. default:
  259. if (s0[i].lbnd < s1[i].lbnd || s0[i].ubnd > s1[i].ubnd)
  260. return (s0[i].lbnd <= s0[i].ubnd ? 0 : 1);
  261. }
  262. break;
  263. }
  264. ras = SCM_CDR (ras);
  265. }
  266. return exact;
  267. }
  268. /* array mapper: apply cproc to each dimension of the given arrays?.
  269. int (*cproc) (); procedure to call on unrolled arrays?
  270. cproc (dest, source list) or
  271. cproc (dest, data, source list).
  272. SCM data; data to give to cproc or unbound.
  273. SCM ra0; destination array.
  274. SCM lra; list of source arrays.
  275. const char *what; caller, for error reporting. */
  276. int
  277. scm_ramapc (int (*cproc)(), SCM data, SCM ra0, SCM lra, const char *what)
  278. {
  279. SCM inds, z;
  280. SCM vra0, ra1, vra1;
  281. SCM lvra, *plvra;
  282. long *vinds;
  283. int k, kmax;
  284. switch (scm_ra_matchp (ra0, lra))
  285. {
  286. default:
  287. case 0:
  288. scm_wta (ra0, "array shape mismatch", what);
  289. case 2:
  290. case 3:
  291. case 4: /* Try unrolling arrays */
  292. kmax = (SCM_ARRAYP (ra0) ? SCM_ARRAY_NDIM (ra0) - 1 : 0);
  293. if (kmax < 0)
  294. goto gencase;
  295. vra0 = scm_array_contents (ra0, SCM_UNDEFINED);
  296. if (SCM_IMP (vra0)) goto gencase;
  297. if (!SCM_ARRAYP (vra0))
  298. {
  299. vra1 = scm_make_ra (1);
  300. SCM_ARRAY_BASE (vra1) = 0;
  301. SCM_ARRAY_DIMS (vra1)->lbnd = 0;
  302. SCM_ARRAY_DIMS (vra1)->ubnd = SCM_LENGTH (vra0) - 1;
  303. SCM_ARRAY_DIMS (vra1)->inc = 1;
  304. SCM_ARRAY_V (vra1) = vra0;
  305. vra0 = vra1;
  306. }
  307. lvra = SCM_EOL;
  308. plvra = &lvra;
  309. for (z = lra; SCM_NIMP (z); z = SCM_CDR (z))
  310. {
  311. ra1 = SCM_CAR (z);
  312. vra1 = scm_make_ra (1);
  313. SCM_ARRAY_DIMS (vra1)->lbnd = SCM_ARRAY_DIMS (vra0)->lbnd;
  314. SCM_ARRAY_DIMS (vra1)->ubnd = SCM_ARRAY_DIMS (vra0)->ubnd;
  315. if (!SCM_ARRAYP (ra1))
  316. {
  317. SCM_ARRAY_BASE (vra1) = 0;
  318. SCM_ARRAY_DIMS (vra1)->inc = 1;
  319. SCM_ARRAY_V (vra1) = ra1;
  320. }
  321. else if (!SCM_ARRAY_CONTP (ra1))
  322. goto gencase;
  323. else
  324. {
  325. SCM_ARRAY_BASE (vra1) = SCM_ARRAY_BASE (ra1);
  326. SCM_ARRAY_DIMS (vra1)->inc = SCM_ARRAY_DIMS (ra1)[kmax].inc;
  327. SCM_ARRAY_V (vra1) = SCM_ARRAY_V (ra1);
  328. }
  329. *plvra = scm_cons (vra1, SCM_EOL);
  330. plvra = SCM_CDRLOC (*plvra);
  331. }
  332. return (SCM_UNBNDP (data) ? cproc(vra0, lvra) : cproc(vra0, data, lvra));
  333. case 1:
  334. gencase: /* Have to loop over all dimensions. */
  335. vra0 = scm_make_ra (1);
  336. if (SCM_ARRAYP (ra0))
  337. {
  338. kmax = SCM_ARRAY_NDIM (ra0) - 1;
  339. if (kmax < 0)
  340. {
  341. SCM_ARRAY_DIMS (vra0)->lbnd = 0;
  342. SCM_ARRAY_DIMS (vra0)->ubnd = 0;
  343. SCM_ARRAY_DIMS (vra0)->inc = 1;
  344. }
  345. else
  346. {
  347. SCM_ARRAY_DIMS (vra0)->lbnd = SCM_ARRAY_DIMS (ra0)[kmax].lbnd;
  348. SCM_ARRAY_DIMS (vra0)->ubnd = SCM_ARRAY_DIMS (ra0)[kmax].ubnd;
  349. SCM_ARRAY_DIMS (vra0)->inc = SCM_ARRAY_DIMS (ra0)[kmax].inc;
  350. }
  351. SCM_ARRAY_BASE (vra0) = SCM_ARRAY_BASE (ra0);
  352. SCM_ARRAY_V (vra0) = SCM_ARRAY_V (ra0);
  353. }
  354. else
  355. {
  356. kmax = 0;
  357. SCM_ARRAY_DIMS (vra0)->lbnd = 0;
  358. SCM_ARRAY_DIMS (vra0)->ubnd = SCM_LENGTH (ra0) - 1;
  359. SCM_ARRAY_DIMS (vra0)->inc = 1;
  360. SCM_ARRAY_BASE (vra0) = 0;
  361. SCM_ARRAY_V (vra0) = ra0;
  362. ra0 = vra0;
  363. }
  364. lvra = SCM_EOL;
  365. plvra = &lvra;
  366. for (z = lra; SCM_NIMP (z); z = SCM_CDR (z))
  367. {
  368. ra1 = SCM_CAR (z);
  369. vra1 = scm_make_ra (1);
  370. SCM_ARRAY_DIMS (vra1)->lbnd = SCM_ARRAY_DIMS (vra0)->lbnd;
  371. SCM_ARRAY_DIMS (vra1)->ubnd = SCM_ARRAY_DIMS (vra0)->ubnd;
  372. if (SCM_ARRAYP (ra1))
  373. {
  374. if (kmax >= 0)
  375. SCM_ARRAY_DIMS (vra1)->inc = SCM_ARRAY_DIMS (ra1)[kmax].inc;
  376. SCM_ARRAY_V (vra1) = SCM_ARRAY_V (ra1);
  377. }
  378. else
  379. {
  380. SCM_ARRAY_DIMS (vra1)->inc = 1;
  381. SCM_ARRAY_V (vra1) = ra1;
  382. }
  383. *plvra = scm_cons (vra1, SCM_EOL);
  384. plvra = SCM_CDRLOC (*plvra);
  385. }
  386. inds = scm_make_uve (SCM_ARRAY_NDIM (ra0), SCM_MAKINUM (-1L));
  387. vinds = (long *) SCM_VELTS (inds);
  388. for (k = 0; k <= kmax; k++)
  389. vinds[k] = SCM_ARRAY_DIMS (ra0)[k].lbnd;
  390. k = kmax;
  391. do
  392. {
  393. if (k == kmax)
  394. {
  395. SCM y = lra;
  396. SCM_ARRAY_BASE (vra0) = cind (ra0, inds);
  397. for (z = lvra; SCM_NIMP (z); z = SCM_CDR (z), y = SCM_CDR (y))
  398. SCM_ARRAY_BASE (SCM_CAR (z)) = cind (SCM_CAR (y), inds);
  399. if (0 == (SCM_UNBNDP (data) ? cproc(vra0, lvra) : cproc(vra0, data, lvra)))
  400. return 0;
  401. k--;
  402. continue;
  403. }
  404. if (vinds[k] < SCM_ARRAY_DIMS (ra0)[k].ubnd)
  405. {
  406. vinds[k]++;
  407. k++;
  408. continue;
  409. }
  410. vinds[k] = SCM_ARRAY_DIMS (ra0)[k].lbnd - 1;
  411. k--;
  412. }
  413. while (k >= 0);
  414. return 1;
  415. }
  416. }
  417. SCM_DEFINE (scm_array_fill_x, "array-fill!", 2, 0, 0,
  418. (SCM ra, SCM fill),
  419. "Stores @var{fill} in every element of @var{array}. The value returned\n"
  420. "is unspecified.")
  421. #define FUNC_NAME s_scm_array_fill_x
  422. {
  423. scm_ramapc (scm_array_fill_int, fill, ra, SCM_EOL, FUNC_NAME);
  424. return SCM_UNSPECIFIED;
  425. }
  426. #undef FUNC_NAME
  427. /* to be used as cproc in scm_ramapc to fill an array dimension with
  428. "fill". */
  429. int
  430. scm_array_fill_int (SCM ra, SCM fill, SCM ignore)
  431. #define FUNC_NAME s_scm_array_fill_x
  432. {
  433. scm_sizet i;
  434. scm_sizet n = SCM_ARRAY_DIMS (ra)->ubnd - SCM_ARRAY_DIMS (ra)->lbnd + 1;
  435. long inc = SCM_ARRAY_DIMS (ra)->inc;
  436. scm_sizet base = SCM_ARRAY_BASE (ra);
  437. ra = SCM_ARRAY_V (ra);
  438. switch SCM_TYP7 (ra)
  439. {
  440. default:
  441. for (i = base; n--; i += inc)
  442. scm_array_set_x (ra, fill, SCM_MAKINUM (i));
  443. break;
  444. case scm_tc7_vector:
  445. case scm_tc7_wvect:
  446. for (i = base; n--; i += inc)
  447. SCM_VELTS (ra)[i] = fill;
  448. break;
  449. case scm_tc7_string:
  450. SCM_ASRTGO (SCM_CHARP (fill), badarg2);
  451. for (i = base; n--; i += inc)
  452. SCM_CHARS (ra)[i] = SCM_CHAR (fill);
  453. break;
  454. case scm_tc7_byvect:
  455. if (SCM_CHARP (fill))
  456. fill = SCM_MAKINUM ((char) SCM_CHAR (fill));
  457. SCM_ASRTGO (SCM_INUMP (fill)
  458. && -128 <= SCM_INUM (fill) && SCM_INUM (fill) < 128,
  459. badarg2);
  460. for (i = base; n--; i += inc)
  461. SCM_CHARS (ra)[i] = SCM_INUM (fill);
  462. break;
  463. case scm_tc7_bvect:
  464. { /* scope */
  465. long *ve = (long *) SCM_VELTS (ra);
  466. if (1 == inc && (n >= SCM_LONG_BIT || n == SCM_LENGTH (ra)))
  467. {
  468. i = base / SCM_LONG_BIT;
  469. if (SCM_FALSEP (fill))
  470. {
  471. if (base % SCM_LONG_BIT) /* leading partial word */
  472. ve[i++] &= ~(~0L << (base % SCM_LONG_BIT));
  473. for (; i < (base + n) / SCM_LONG_BIT; i++)
  474. ve[i] = 0L;
  475. if ((base + n) % SCM_LONG_BIT) /* trailing partial word */
  476. ve[i] &= (~0L << ((base + n) % SCM_LONG_BIT));
  477. }
  478. else if (SCM_EQ_P (fill, SCM_BOOL_T))
  479. {
  480. if (base % SCM_LONG_BIT)
  481. ve[i++] |= ~0L << (base % SCM_LONG_BIT);
  482. for (; i < (base + n) / SCM_LONG_BIT; i++)
  483. ve[i] = ~0L;
  484. if ((base + n) % SCM_LONG_BIT)
  485. ve[i] |= ~(~0L << ((base + n) % SCM_LONG_BIT));
  486. }
  487. else
  488. badarg2:SCM_WTA (2,fill);
  489. }
  490. else
  491. {
  492. if (SCM_FALSEP (fill))
  493. for (i = base; n--; i += inc)
  494. ve[i / SCM_LONG_BIT] &= ~(1L << (i % SCM_LONG_BIT));
  495. else if (SCM_EQ_P (fill, SCM_BOOL_T))
  496. for (i = base; n--; i += inc)
  497. ve[i / SCM_LONG_BIT] |= (1L << (i % SCM_LONG_BIT));
  498. else
  499. goto badarg2;
  500. }
  501. break;
  502. }
  503. case scm_tc7_uvect:
  504. { /* scope */
  505. unsigned long f = SCM_NUM2ULONG (2,fill);
  506. unsigned long *ve = (unsigned long *) SCM_VELTS (ra);
  507. for (i = base; n--; i += inc)
  508. ve[i] = f;
  509. break;
  510. }
  511. case scm_tc7_ivect:
  512. { /* scope */
  513. long f = SCM_NUM2LONG (2,fill);
  514. long *ve = (long *) SCM_VELTS (ra);
  515. for (i = base; n--; i += inc)
  516. ve[i] = f;
  517. break;
  518. }
  519. case scm_tc7_svect:
  520. SCM_ASRTGO (SCM_INUMP (fill), badarg2);
  521. { /* scope */
  522. short f = SCM_INUM (fill);
  523. short *ve = (short *) SCM_VELTS (ra);
  524. if (f != SCM_INUM (fill))
  525. SCM_OUT_OF_RANGE (2, fill);
  526. for (i = base; n--; i += inc)
  527. ve[i] = f;
  528. break;
  529. }
  530. #ifdef HAVE_LONG_LONGS
  531. case scm_tc7_llvect:
  532. { /* scope */
  533. long long f = SCM_NUM2LONG_LONG (2,fill);
  534. long long *ve = (long long *) SCM_VELTS (ra);
  535. for (i = base; n--; i += inc)
  536. ve[i] = f;
  537. break;
  538. }
  539. #endif
  540. case scm_tc7_fvect:
  541. { /* scope */
  542. float f, *ve = (float *) SCM_VELTS (ra);
  543. SCM_ASRTGO (SCM_REALP (fill), badarg2);
  544. f = SCM_REAL_VALUE (fill);
  545. for (i = base; n--; i += inc)
  546. ve[i] = f;
  547. break;
  548. }
  549. case scm_tc7_dvect:
  550. { /* scope */
  551. double f, *ve = (double *) SCM_VELTS (ra);
  552. SCM_ASRTGO (SCM_REALP (fill), badarg2);
  553. f = SCM_REAL_VALUE (fill);
  554. for (i = base; n--; i += inc)
  555. ve[i] = f;
  556. break;
  557. }
  558. case scm_tc7_cvect:
  559. { /* scope */
  560. double fr, fi;
  561. double (*ve)[2] = (double (*)[2]) SCM_VELTS (ra);
  562. SCM_ASRTGO (SCM_INEXACTP (fill), badarg2);
  563. if (SCM_REALP (fill)) {
  564. fr = SCM_REAL_VALUE (fill);
  565. fi = 0.0;
  566. } else {
  567. fr = SCM_COMPLEX_REAL (fill);
  568. fi = SCM_COMPLEX_IMAG (fill);
  569. }
  570. for (i = base; n--; i += inc)
  571. {
  572. ve[i][0] = fr;
  573. ve[i][1] = fi;
  574. }
  575. break;
  576. }
  577. }
  578. return 1;
  579. }
  580. #undef FUNC_NAME
  581. static int
  582. racp (SCM src, SCM dst)
  583. {
  584. long n = (SCM_ARRAY_DIMS (src)->ubnd - SCM_ARRAY_DIMS (src)->lbnd + 1);
  585. long inc_d, inc_s = SCM_ARRAY_DIMS (src)->inc;
  586. scm_sizet i_d, i_s = SCM_ARRAY_BASE (src);
  587. dst = SCM_CAR (dst);
  588. inc_d = SCM_ARRAY_DIMS (dst)->inc;
  589. i_d = SCM_ARRAY_BASE (dst);
  590. src = SCM_ARRAY_V (src);
  591. dst = SCM_ARRAY_V (dst);
  592. /* untested optimization: don't copy if we're we. This allows the
  593. ugly UNICOS macros (IVDEP) to go .
  594. */
  595. if (SCM_EQ_P (src, dst))
  596. return 1 ;
  597. switch SCM_TYP7
  598. (dst)
  599. {
  600. default:
  601. gencase:
  602. case scm_tc7_vector:
  603. case scm_tc7_wvect:
  604. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  605. scm_array_set_x (dst, scm_cvref (src, i_s, SCM_UNDEFINED), SCM_MAKINUM (i_d));
  606. break;
  607. case scm_tc7_string:
  608. case scm_tc7_byvect:
  609. if (scm_tc7_string != SCM_TYP7 (dst))
  610. goto gencase;
  611. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  612. SCM_CHARS (dst)[i_d] = SCM_CHARS (src)[i_s];
  613. break;
  614. case scm_tc7_bvect:
  615. if (scm_tc7_bvect != SCM_TYP7 (dst))
  616. goto gencase;
  617. if (1 == inc_d && 1 == inc_s && i_s % SCM_LONG_BIT == i_d % SCM_LONG_BIT && n >= SCM_LONG_BIT)
  618. {
  619. long *sv = (long *) SCM_VELTS (src);
  620. long *dv = (long *) SCM_VELTS (dst);
  621. sv += i_s / SCM_LONG_BIT;
  622. dv += i_d / SCM_LONG_BIT;
  623. if (i_s % SCM_LONG_BIT)
  624. { /* leading partial word */
  625. *dv = (*dv & ~(~0L << (i_s % SCM_LONG_BIT))) | (*sv & (~0L << (i_s % SCM_LONG_BIT)));
  626. dv++;
  627. sv++;
  628. n -= SCM_LONG_BIT - (i_s % SCM_LONG_BIT);
  629. }
  630. for (; n >= SCM_LONG_BIT; n -= SCM_LONG_BIT, sv++, dv++)
  631. * dv = *sv;
  632. if (n) /* trailing partial word */
  633. *dv = (*dv & (~0L << n)) | (*sv & ~(~0L << n));
  634. }
  635. else
  636. {
  637. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  638. if (SCM_BITVEC_REF(src, i_s))
  639. SCM_BITVEC_SET(dst, i_d);
  640. else
  641. SCM_BITVEC_CLR(dst, i_d);
  642. }
  643. break;
  644. case scm_tc7_uvect:
  645. if (scm_tc7_uvect != SCM_TYP7 (src))
  646. goto gencase;
  647. else
  648. {
  649. long *d = (long *) SCM_VELTS (dst), *s = (long *) SCM_VELTS (src);
  650. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  651. d[i_d] = s[i_s];
  652. break;
  653. }
  654. case scm_tc7_ivect:
  655. if (scm_tc7_uvect != SCM_TYP7 (src) && scm_tc7_ivect != SCM_TYP7 (src))
  656. goto gencase;
  657. else
  658. {
  659. long *d = (long *) SCM_VELTS (dst), *s = (long *) SCM_VELTS (src);
  660. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  661. d[i_d] = s[i_s];
  662. break;
  663. }
  664. case scm_tc7_fvect:
  665. {
  666. float *d = (float *) SCM_VELTS (dst);
  667. float *s = (float *) SCM_VELTS (src);
  668. switch SCM_TYP7
  669. (src)
  670. {
  671. default:
  672. goto gencase;
  673. case scm_tc7_ivect:
  674. case scm_tc7_uvect:
  675. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  676. d[i_d] = ((long *) s)[i_s];
  677. break;
  678. case scm_tc7_fvect:
  679. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  680. d[i_d] = s[i_s];
  681. break;
  682. case scm_tc7_dvect:
  683. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  684. d[i_d] = ((double *) s)[i_s];
  685. break;
  686. }
  687. break;
  688. }
  689. case scm_tc7_dvect:
  690. {
  691. double *d = (double *) SCM_VELTS (dst);
  692. double *s = (double *) SCM_VELTS (src);
  693. switch SCM_TYP7
  694. (src)
  695. {
  696. default:
  697. goto gencase;
  698. case scm_tc7_ivect:
  699. case scm_tc7_uvect:
  700. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  701. d[i_d] = ((long *) s)[i_s];
  702. break;
  703. case scm_tc7_fvect:
  704. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  705. d[i_d] = ((float *) s)[i_s];
  706. break;
  707. case scm_tc7_dvect:
  708. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  709. d[i_d] = s[i_s];
  710. break;
  711. }
  712. break;
  713. }
  714. case scm_tc7_cvect:
  715. {
  716. double (*d)[2] = (double (*)[2]) SCM_VELTS (dst);
  717. double (*s)[2] = (double (*)[2]) SCM_VELTS (src);
  718. switch SCM_TYP7
  719. (src)
  720. {
  721. default:
  722. goto gencase;
  723. case scm_tc7_ivect:
  724. case scm_tc7_uvect:
  725. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  726. {
  727. d[i_d][0] = ((long *) s)[i_s];
  728. d[i_d][1] = 0.0;
  729. }
  730. break;
  731. case scm_tc7_fvect:
  732. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  733. {
  734. d[i_d][0] = ((float *) s)[i_s];
  735. d[i_d][1] = 0.0;
  736. }
  737. break;
  738. case scm_tc7_dvect:
  739. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  740. {
  741. d[i_d][0] = ((double *) s)[i_s];
  742. d[i_d][1] = 0.0;
  743. }
  744. break;
  745. case scm_tc7_cvect:
  746. for (; n-- > 0; i_s += inc_s, i_d += inc_d)
  747. {
  748. d[i_d][0] = s[i_s][0];
  749. d[i_d][1] = s[i_s][1];
  750. }
  751. }
  752. break;
  753. }
  754. }
  755. return 1;
  756. }
  757. SCM_REGISTER_PROC(s_array_copy_in_order_x, "array-copy-in-order!", 2, 0, 0, scm_array_copy_x);
  758. SCM_DEFINE (scm_array_copy_x, "array-copy!", 2, 0, 0,
  759. (SCM src, SCM dst),
  760. "Copies every element from vector or array @var{source} to the\n"
  761. "corresponding element of @var{destination}. @var{destination} must have\n"
  762. "the same rank as @var{source}, and be at least as large in each\n"
  763. "dimension. The order is unspecified.")
  764. #define FUNC_NAME s_scm_array_copy_x
  765. {
  766. scm_ramapc (racp, SCM_UNDEFINED, src, scm_cons (dst, SCM_EOL), FUNC_NAME);
  767. return SCM_UNSPECIFIED;
  768. }
  769. #undef FUNC_NAME
  770. /* Functions callable by ARRAY-MAP! */
  771. int
  772. scm_ra_eqp (SCM ra0, SCM ras)
  773. {
  774. SCM ra1 = SCM_CAR (ras), ra2 = SCM_CAR (SCM_CDR (ras));
  775. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  776. scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
  777. long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
  778. long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  779. long inc2 = SCM_ARRAY_DIMS (ra1)->inc;
  780. ra0 = SCM_ARRAY_V (ra0);
  781. ra1 = SCM_ARRAY_V (ra1);
  782. ra2 = SCM_ARRAY_V (ra2);
  783. switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
  784. {
  785. default:
  786. {
  787. SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
  788. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  789. if (SCM_BITVEC_REF (ra0, i0))
  790. if (SCM_FALSEP(scm_eq_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))))
  791. SCM_BITVEC_CLR (ra0, i0);
  792. break;
  793. }
  794. case scm_tc7_uvect:
  795. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  796. if (SCM_BITVEC_REF (ra0, i0))
  797. if (((unsigned long *) SCM_VELTS (ra1))[i1] != ((unsigned long *) SCM_VELTS (ra2))[i2])
  798. SCM_BITVEC_CLR (ra0, i0);
  799. break;
  800. case scm_tc7_ivect:
  801. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  802. if (SCM_BITVEC_REF (ra0, i0))
  803. if (((signed long *) SCM_VELTS (ra1))[i1] != ((signed long *) SCM_VELTS (ra2))[i2])
  804. SCM_BITVEC_CLR (ra0, i0);
  805. break;
  806. case scm_tc7_fvect:
  807. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  808. if (SCM_BITVEC_REF (ra0, i0))
  809. if (((float *) SCM_VELTS (ra1))[i1] != ((float *) SCM_VELTS (ra2))[i2])
  810. SCM_BITVEC_CLR (ra0, i0);
  811. break;
  812. case scm_tc7_dvect:
  813. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  814. if (SCM_BITVEC_REF (ra0, i0))
  815. if (((double *) SCM_VELTS (ra1))[i1] != ((double *) SCM_VELTS (ra2))[i2])
  816. SCM_BITVEC_CLR (ra0, i0);
  817. break;
  818. case scm_tc7_cvect:
  819. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  820. if (SCM_BITVEC_REF (ra0, i0))
  821. if (((double *) SCM_VELTS (ra1))[2 * i1] != ((double *) SCM_VELTS (ra2))[2 * i2] ||
  822. ((double *) SCM_VELTS (ra1))[2 * i1 + 1] != ((double *) SCM_VELTS (ra2))[2 * i2 + 1])
  823. SCM_BITVEC_CLR (ra0, i0);
  824. break;
  825. }
  826. return 1;
  827. }
  828. /* opt 0 means <, nonzero means >= */
  829. static int
  830. ra_compare (SCM ra0,SCM ra1,SCM ra2,int opt)
  831. {
  832. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  833. scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
  834. long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
  835. long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  836. long inc2 = SCM_ARRAY_DIMS (ra1)->inc;
  837. ra0 = SCM_ARRAY_V (ra0);
  838. ra1 = SCM_ARRAY_V (ra1);
  839. ra2 = SCM_ARRAY_V (ra2);
  840. switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
  841. {
  842. default:
  843. {
  844. SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
  845. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  846. if (SCM_BITVEC_REF (ra0, i0))
  847. if (opt ?
  848. SCM_NFALSEP (scm_less_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))) :
  849. SCM_FALSEP (scm_less_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))))
  850. SCM_BITVEC_CLR (ra0, i0);
  851. break;
  852. }
  853. case scm_tc7_uvect:
  854. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  855. {
  856. if (SCM_BITVEC_REF (ra0, i0))
  857. if (opt ?
  858. ((unsigned long *) SCM_VELTS (ra1))[i1] < ((unsigned long *) SCM_VELTS (ra2))[i2] :
  859. ((unsigned long *) SCM_VELTS (ra1))[i1] >= ((unsigned long *) SCM_VELTS (ra2))[i2])
  860. SCM_BITVEC_CLR (ra0, i0);
  861. }
  862. break;
  863. case scm_tc7_ivect:
  864. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  865. {
  866. if (SCM_BITVEC_REF (ra0, i0))
  867. if (opt ?
  868. ((signed long *) SCM_VELTS (ra1))[i1] < ((signed long *) SCM_VELTS (ra2))[i2] :
  869. ((signed long *) SCM_VELTS (ra1))[i1] >= ((signed long *) SCM_VELTS (ra2))[i2])
  870. SCM_BITVEC_CLR (ra0, i0);
  871. }
  872. break;
  873. case scm_tc7_fvect:
  874. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  875. if (SCM_BITVEC_REF(ra0, i0))
  876. if (opt ?
  877. ((float *) SCM_VELTS (ra1))[i1] < ((float *) SCM_VELTS (ra2))[i2] :
  878. ((float *) SCM_VELTS (ra1))[i1] >= ((float *) SCM_VELTS (ra2))[i2])
  879. SCM_BITVEC_CLR (ra0, i0);
  880. break;
  881. case scm_tc7_dvect:
  882. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  883. if (SCM_BITVEC_REF (ra0, i0))
  884. if (opt ?
  885. ((double *) SCM_VELTS (ra1))[i1] < ((double *) SCM_VELTS (ra2))[i2] :
  886. ((double *) SCM_VELTS (ra1))[i1] >= ((double *) SCM_VELTS (ra2))[i2])
  887. SCM_BITVEC_CLR (ra0, i0);
  888. break;
  889. }
  890. return 1;
  891. }
  892. int
  893. scm_ra_lessp (SCM ra0, SCM ras)
  894. {
  895. return ra_compare (ra0, SCM_CAR (ras), SCM_CAR (SCM_CDR (ras)), 0);
  896. }
  897. int
  898. scm_ra_leqp (SCM ra0, SCM ras)
  899. {
  900. return ra_compare (ra0, SCM_CAR (SCM_CDR (ras)), SCM_CAR (ras), 1);
  901. }
  902. int
  903. scm_ra_grp (SCM ra0, SCM ras)
  904. {
  905. return ra_compare (ra0, SCM_CAR (SCM_CDR (ras)), SCM_CAR (ras), 0);
  906. }
  907. int
  908. scm_ra_greqp (SCM ra0, SCM ras)
  909. {
  910. return ra_compare (ra0, SCM_CAR (ras), SCM_CAR (SCM_CDR (ras)), 1);
  911. }
  912. int
  913. scm_ra_sum (SCM ra0, SCM ras)
  914. {
  915. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  916. scm_sizet i0 = SCM_ARRAY_BASE (ra0);
  917. long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
  918. ra0 = SCM_ARRAY_V (ra0);
  919. if (SCM_NNULLP(ras))
  920. {
  921. SCM ra1 = SCM_CAR (ras);
  922. scm_sizet i1 = SCM_ARRAY_BASE (ra1);
  923. long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  924. ra1 = SCM_ARRAY_V (ra1);
  925. switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
  926. {
  927. default:
  928. {
  929. SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
  930. for (; n-- > 0; i0 += inc0, i1 += inc1)
  931. scm_array_set_x (ra0, scm_sum (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
  932. SCM_MAKINUM (i0));
  933. break;
  934. }
  935. case scm_tc7_uvect:
  936. case scm_tc7_ivect:
  937. BINARY_ELTS_CODE( +=, long);
  938. case scm_tc7_fvect:
  939. BINARY_ELTS_CODE( +=, float);
  940. case scm_tc7_dvect:
  941. BINARY_ELTS_CODE( +=, double);
  942. case scm_tc7_cvect:
  943. BINARY_PAIR_ELTS_CODE( +=, double);
  944. }
  945. }
  946. return 1;
  947. }
  948. int
  949. scm_ra_difference (SCM ra0, SCM ras)
  950. {
  951. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  952. scm_sizet i0 = SCM_ARRAY_BASE (ra0);
  953. long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
  954. ra0 = SCM_ARRAY_V (ra0);
  955. if (SCM_NULLP (ras))
  956. {
  957. switch (SCM_TYP7 (ra0))
  958. {
  959. default:
  960. {
  961. SCM e0 = SCM_UNDEFINED;
  962. for (; n-- > 0; i0 += inc0)
  963. scm_array_set_x (ra0,
  964. scm_difference (RVREF (ra0, i0, e0), SCM_UNDEFINED),
  965. SCM_MAKINUM (i0));
  966. break;
  967. }
  968. case scm_tc7_fvect:
  969. UNARY_ELTS_CODE( = -, float);
  970. case scm_tc7_dvect:
  971. UNARY_ELTS_CODE( = -, double);
  972. case scm_tc7_cvect:
  973. UNARY_PAIR_ELTS_CODE( = -, double);
  974. }
  975. }
  976. else
  977. {
  978. SCM ra1 = SCM_CAR (ras);
  979. scm_sizet i1 = SCM_ARRAY_BASE (ra1);
  980. long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  981. ra1 = SCM_ARRAY_V (ra1);
  982. switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
  983. {
  984. default:
  985. {
  986. SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
  987. for (; n-- > 0; i0 += inc0, i1 += inc1)
  988. scm_array_set_x (ra0, scm_difference (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)), SCM_MAKINUM (i0));
  989. break;
  990. }
  991. case scm_tc7_fvect:
  992. BINARY_ELTS_CODE( -=, float);
  993. case scm_tc7_dvect:
  994. BINARY_ELTS_CODE( -=, double);
  995. case scm_tc7_cvect:
  996. BINARY_PAIR_ELTS_CODE( -=, double);
  997. }
  998. }
  999. return 1;
  1000. }
  1001. int
  1002. scm_ra_product (SCM ra0, SCM ras)
  1003. {
  1004. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  1005. scm_sizet i0 = SCM_ARRAY_BASE (ra0);
  1006. long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
  1007. ra0 = SCM_ARRAY_V (ra0);
  1008. if (SCM_NNULLP (ras))
  1009. {
  1010. SCM ra1 = SCM_CAR (ras);
  1011. scm_sizet i1 = SCM_ARRAY_BASE (ra1);
  1012. long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  1013. ra1 = SCM_ARRAY_V (ra1);
  1014. switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
  1015. {
  1016. default:
  1017. {
  1018. SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
  1019. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1020. scm_array_set_x (ra0, scm_product (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
  1021. SCM_MAKINUM (i0));
  1022. break;
  1023. }
  1024. case scm_tc7_uvect:
  1025. case scm_tc7_ivect:
  1026. BINARY_ELTS_CODE( *=, long);
  1027. case scm_tc7_fvect:
  1028. BINARY_ELTS_CODE( *=, float);
  1029. case scm_tc7_dvect:
  1030. BINARY_ELTS_CODE( *=, double);
  1031. case scm_tc7_cvect:
  1032. {
  1033. double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
  1034. register double r;
  1035. double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1);
  1036. IVDEP (ra0 != ra1,
  1037. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1038. {
  1039. r = v0[i0][0] * v1[i1][0] - v0[i0][1] * v1[i1][1];
  1040. v0[i0][1] = v0[i0][0] * v1[i1][1] + v0[i0][1] * v1[i1][0];
  1041. v0[i0][0] = r;
  1042. }
  1043. );
  1044. break;
  1045. }
  1046. }
  1047. }
  1048. return 1;
  1049. }
  1050. int
  1051. scm_ra_divide (SCM ra0, SCM ras)
  1052. {
  1053. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  1054. scm_sizet i0 = SCM_ARRAY_BASE (ra0);
  1055. long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
  1056. ra0 = SCM_ARRAY_V (ra0);
  1057. if (SCM_NULLP (ras))
  1058. {
  1059. switch (SCM_TYP7 (ra0))
  1060. {
  1061. default:
  1062. {
  1063. SCM e0 = SCM_UNDEFINED;
  1064. for (; n-- > 0; i0 += inc0)
  1065. scm_array_set_x (ra0, scm_divide (RVREF (ra0, i0, e0), SCM_UNDEFINED), SCM_MAKINUM (i0));
  1066. break;
  1067. }
  1068. case scm_tc7_fvect:
  1069. UNARY_ELTS_CODE( = 1.0 / , float);
  1070. case scm_tc7_dvect:
  1071. UNARY_ELTS_CODE( = 1.0 / , double);
  1072. case scm_tc7_cvect:
  1073. {
  1074. register double d;
  1075. double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
  1076. for (; n-- > 0; i0 += inc0)
  1077. {
  1078. d = v0[i0][0] * v0[i0][0] + v0[i0][1] * v0[i0][1];
  1079. v0[i0][0] /= d;
  1080. v0[i0][1] /= -d;
  1081. }
  1082. break;
  1083. }
  1084. }
  1085. }
  1086. else
  1087. {
  1088. SCM ra1 = SCM_CAR (ras);
  1089. scm_sizet i1 = SCM_ARRAY_BASE (ra1);
  1090. long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  1091. ra1 = SCM_ARRAY_V (ra1);
  1092. switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
  1093. {
  1094. default:
  1095. {
  1096. SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
  1097. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1098. scm_array_set_x (ra0, scm_divide (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)), SCM_MAKINUM (i0));
  1099. break;
  1100. }
  1101. case scm_tc7_fvect:
  1102. BINARY_ELTS_CODE( /=, float);
  1103. case scm_tc7_dvect:
  1104. BINARY_ELTS_CODE( /=, double);
  1105. case scm_tc7_cvect:
  1106. {
  1107. register double d, r;
  1108. double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
  1109. double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1);
  1110. IVDEP (ra0 != ra1,
  1111. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1112. {
  1113. d = v1[i1][0] * v1[i1][0] + v1[i1][1] * v1[i1][1];
  1114. r = (v0[i0][0] * v1[i1][0] + v0[i0][1] * v1[i1][1]) / d;
  1115. v0[i0][1] = (v0[i0][1] * v1[i1][0] - v0[i0][0] * v1[i1][1]) / d;
  1116. v0[i0][0] = r;
  1117. }
  1118. )
  1119. break;
  1120. }
  1121. }
  1122. }
  1123. return 1;
  1124. }
  1125. int
  1126. scm_array_identity (SCM dst, SCM src)
  1127. {
  1128. return racp (SCM_CAR (src), scm_cons (dst, SCM_EOL));
  1129. }
  1130. static int
  1131. ramap (SCM ra0,SCM proc,SCM ras)
  1132. {
  1133. long i = SCM_ARRAY_DIMS (ra0)->lbnd;
  1134. long inc = SCM_ARRAY_DIMS (ra0)->inc;
  1135. long n = SCM_ARRAY_DIMS (ra0)->ubnd;
  1136. long base = SCM_ARRAY_BASE (ra0) - i * inc;
  1137. ra0 = SCM_ARRAY_V (ra0);
  1138. if (SCM_NULLP (ras))
  1139. for (; i <= n; i++)
  1140. scm_array_set_x (ra0, scm_apply (proc, SCM_EOL, SCM_EOL), SCM_MAKINUM (i * inc + base));
  1141. else
  1142. {
  1143. SCM ra1 = SCM_CAR (ras);
  1144. SCM args, *ve = &ras;
  1145. scm_sizet k, i1 = SCM_ARRAY_BASE (ra1);
  1146. long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  1147. ra1 = SCM_ARRAY_V (ra1);
  1148. ras = SCM_CDR (ras);
  1149. if (SCM_NULLP(ras))
  1150. ras = scm_nullvect;
  1151. else
  1152. {
  1153. ras = scm_vector (ras);
  1154. ve = SCM_VELTS (ras);
  1155. }
  1156. for (; i <= n; i++, i1 += inc1)
  1157. {
  1158. args = SCM_EOL;
  1159. for (k = SCM_LENGTH (ras); k--;)
  1160. args = scm_cons (scm_uniform_vector_ref (ve[k], SCM_MAKINUM (i)), args);
  1161. args = scm_cons (scm_cvref (ra1, i1, SCM_UNDEFINED), args);
  1162. scm_array_set_x (ra0, scm_apply (proc, args, SCM_EOL), SCM_MAKINUM (i * inc + base));
  1163. }
  1164. }
  1165. return 1;
  1166. }
  1167. static int
  1168. ramap_cxr (SCM ra0,SCM proc,SCM ras)
  1169. {
  1170. SCM ra1 = SCM_CAR (ras);
  1171. SCM e1 = SCM_UNDEFINED;
  1172. scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
  1173. long inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  1174. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra1)->lbnd + 1;
  1175. ra0 = SCM_ARRAY_V (ra0);
  1176. ra1 = SCM_ARRAY_V (ra1);
  1177. switch (SCM_TYP7 (ra0))
  1178. {
  1179. default:
  1180. gencase:
  1181. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1182. scm_array_set_x (ra0, scm_apply (proc, RVREF (ra1, i1, e1), scm_listofnull), SCM_MAKINUM (i0));
  1183. break;
  1184. case scm_tc7_fvect:
  1185. {
  1186. float *dst = (float *) SCM_VELTS (ra0);
  1187. switch (SCM_TYP7 (ra1))
  1188. {
  1189. default:
  1190. goto gencase;
  1191. case scm_tc7_fvect:
  1192. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1193. dst[i0] = SCM_DSUBRF (proc) ((double) ((float *) SCM_VELTS (ra1))[i1]);
  1194. break;
  1195. case scm_tc7_uvect:
  1196. case scm_tc7_ivect:
  1197. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1198. dst[i0] = SCM_DSUBRF (proc) (SCM_UNPACK (SCM_VELTS (ra1)[i1]));
  1199. break;
  1200. }
  1201. break;
  1202. }
  1203. case scm_tc7_dvect:
  1204. {
  1205. double *dst = (double *) SCM_VELTS (ra0);
  1206. switch (SCM_TYP7 (ra1))
  1207. {
  1208. default:
  1209. goto gencase;
  1210. case scm_tc7_dvect:
  1211. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1212. dst[i0] = SCM_DSUBRF (proc) (((double *) SCM_VELTS (ra1))[i1]);
  1213. break;
  1214. case scm_tc7_uvect:
  1215. case scm_tc7_ivect:
  1216. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1217. dst[i0] = SCM_DSUBRF (proc) (SCM_UNPACK (SCM_VELTS (ra1)[i1]));
  1218. break;
  1219. }
  1220. break;
  1221. }
  1222. }
  1223. return 1;
  1224. }
  1225. static int
  1226. ramap_rp (SCM ra0,SCM proc,SCM ras)
  1227. {
  1228. SCM ra1 = SCM_CAR (ras), ra2 = SCM_CAR (SCM_CDR (ras));
  1229. SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
  1230. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  1231. scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
  1232. long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
  1233. long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  1234. long inc2 = SCM_ARRAY_DIMS (ra1)->inc;
  1235. ra0 = SCM_ARRAY_V (ra0);
  1236. ra1 = SCM_ARRAY_V (ra1);
  1237. ra2 = SCM_ARRAY_V (ra2);
  1238. switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
  1239. {
  1240. default:
  1241. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  1242. if (SCM_BITVEC_REF (ra0, i0))
  1243. if (SCM_FALSEP (SCM_SUBRF (proc) (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))))
  1244. SCM_BITVEC_CLR (ra0, i0);
  1245. break;
  1246. case scm_tc7_uvect:
  1247. case scm_tc7_ivect:
  1248. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  1249. if (SCM_BITVEC_REF (ra0, i0))
  1250. {
  1251. /* DIRK:FIXME:: There should be a way to access the elements
  1252. of a cell as raw data. Further: How can we be sure that
  1253. the values fit into an inum?
  1254. */
  1255. SCM n1 = SCM_MAKINUM (((long *) SCM_UNPACK (SCM_CDR (ra1)))[i1]);
  1256. SCM n2 = SCM_MAKINUM (((long *) SCM_UNPACK (SCM_CDR (ra2)))[i2]);
  1257. if (SCM_FALSEP (SCM_SUBRF (proc) (n1, n2)));
  1258. SCM_BITVEC_CLR (ra0, i0);
  1259. }
  1260. break;
  1261. case scm_tc7_fvect:
  1262. {
  1263. SCM a1 = scm_make_real (1.0), a2 = scm_make_real (1.0);
  1264. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  1265. if (SCM_BITVEC_REF (ra0, i0))
  1266. {
  1267. SCM_REAL_VALUE (a1) = ((float *) SCM_VELTS (ra1))[i1];
  1268. SCM_REAL_VALUE (a2) = ((float *) SCM_VELTS (ra2))[i2];
  1269. if (SCM_FALSEP (SCM_SUBRF (proc) (a1, a2)))
  1270. SCM_BITVEC_CLR (ra0, i0);
  1271. }
  1272. break;
  1273. }
  1274. case scm_tc7_dvect:
  1275. {
  1276. SCM a1 = scm_make_real (1.0 / 3.0);
  1277. SCM a2 = scm_make_real (1.0 / 3.0);
  1278. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  1279. if (SCM_BITVEC_REF (ra0, i0))
  1280. {
  1281. SCM_REAL_VALUE (a1) = ((double *) SCM_VELTS (ra1))[i1];
  1282. SCM_REAL_VALUE (a2) = ((double *) SCM_VELTS (ra2))[i2];
  1283. if (SCM_FALSEP (SCM_SUBRF (proc) (a1, a2)))
  1284. SCM_BITVEC_CLR (ra0, i0);
  1285. }
  1286. break;
  1287. }
  1288. case scm_tc7_cvect:
  1289. {
  1290. SCM a1 = scm_make_complex (1.0, 1.0);
  1291. SCM a2 = scm_make_complex (1.0, 1.0);
  1292. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  1293. if (SCM_BITVEC_REF (ra0, i0))
  1294. {
  1295. SCM_COMPLEX_REAL (a1) = ((double *) SCM_VELTS (ra1))[2 * i1];
  1296. SCM_COMPLEX_IMAG (a1) = ((double *) SCM_VELTS (ra1))[2 * i1 + 1];
  1297. SCM_COMPLEX_REAL (a2) = ((double *) SCM_VELTS (ra2))[2 * i2];
  1298. SCM_COMPLEX_IMAG (a2) = ((double *) SCM_VELTS (ra2))[2 * i2 + 1];
  1299. if (SCM_FALSEP (SCM_SUBRF (proc) (a1, a2)))
  1300. SCM_BITVEC_CLR (ra0, i0);
  1301. }
  1302. break;
  1303. }
  1304. }
  1305. return 1;
  1306. }
  1307. static int
  1308. ramap_1 (SCM ra0,SCM proc,SCM ras)
  1309. {
  1310. SCM ra1 = SCM_CAR (ras);
  1311. SCM e1 = SCM_UNDEFINED;
  1312. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  1313. scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
  1314. long inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  1315. ra0 = SCM_ARRAY_V (ra0);
  1316. ra1 = SCM_ARRAY_V (ra1);
  1317. if (scm_tc7_vector == SCM_TYP7 (ra0) || scm_tc7_wvect == SCM_TYP7 (ra0))
  1318. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1319. scm_array_set_x (ra0, SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED)), SCM_MAKINUM (i0));
  1320. else
  1321. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1322. scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra1, i1, e1)), SCM_MAKINUM (i0));
  1323. return 1;
  1324. }
  1325. static int
  1326. ramap_2o (SCM ra0,SCM proc,SCM ras)
  1327. {
  1328. SCM ra1 = SCM_CAR (ras);
  1329. SCM e1 = SCM_UNDEFINED;
  1330. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  1331. scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
  1332. long inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  1333. ra0 = SCM_ARRAY_V (ra0);
  1334. ra1 = SCM_ARRAY_V (ra1);
  1335. ras = SCM_CDR (ras);
  1336. if (SCM_NULLP (ras))
  1337. {
  1338. if (scm_tc7_vector == SCM_TYP7 (ra0)
  1339. || scm_tc7_wvect == SCM_TYP7 (ra0))
  1340. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1341. scm_array_set_x (ra0, SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED), SCM_UNDEFINED),
  1342. SCM_MAKINUM (i0));
  1343. else
  1344. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1345. scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra1, i1, e1), SCM_UNDEFINED),
  1346. SCM_MAKINUM (i0));
  1347. }
  1348. else
  1349. {
  1350. SCM ra2 = SCM_CAR (ras);
  1351. SCM e2 = SCM_UNDEFINED;
  1352. scm_sizet i2 = SCM_ARRAY_BASE (ra2);
  1353. long inc2 = SCM_ARRAY_DIMS (ra2)->inc;
  1354. ra2 = SCM_ARRAY_V (ra2);
  1355. if (scm_tc7_vector == SCM_TYP7 (ra0) || scm_tc7_wvect == SCM_TYP7 (ra0))
  1356. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  1357. scm_array_set_x (ra0,
  1358. SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED), scm_cvref (ra2, i2, SCM_UNDEFINED)),
  1359. SCM_MAKINUM (i0));
  1360. else
  1361. for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
  1362. scm_array_set_x (ra0,
  1363. SCM_SUBRF (proc) (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2)),
  1364. SCM_MAKINUM (i0));
  1365. }
  1366. return 1;
  1367. }
  1368. static int
  1369. ramap_a (SCM ra0,SCM proc,SCM ras)
  1370. {
  1371. SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
  1372. long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  1373. scm_sizet i0 = SCM_ARRAY_BASE (ra0);
  1374. long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
  1375. ra0 = SCM_ARRAY_V (ra0);
  1376. if (SCM_NULLP (ras))
  1377. for (; n-- > 0; i0 += inc0)
  1378. scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra0, i0, e0), SCM_UNDEFINED), SCM_MAKINUM (i0));
  1379. else
  1380. {
  1381. SCM ra1 = SCM_CAR (ras);
  1382. scm_sizet i1 = SCM_ARRAY_BASE (ra1);
  1383. long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  1384. ra1 = SCM_ARRAY_V (ra1);
  1385. for (; n-- > 0; i0 += inc0, i1 += inc1)
  1386. scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
  1387. SCM_MAKINUM (i0));
  1388. }
  1389. return 1;
  1390. }
  1391. SCM_REGISTER_PROC(s_array_map_in_order_x, "array-map-in-order!", 2, 0, 1, scm_array_map_x);
  1392. SCM_DEFINE (scm_array_map_x, "array-map!", 2, 0, 1,
  1393. (SCM ra0, SCM proc, SCM lra),
  1394. "@var{array1}, @dots{} must have the same number of dimensions as\n"
  1395. "@var{array0} and have a range for each index which includes the range\n"
  1396. "for the corresponding index in @var{array0}. @var{proc} is applied to\n"
  1397. "each tuple of elements of @var{array1} @dots{} and the result is stored\n"
  1398. "as the corresponding element in @var{array0}. The value returned is\n"
  1399. "unspecified. The order of application is unspecified.")
  1400. #define FUNC_NAME s_scm_array_map_x
  1401. {
  1402. SCM_VALIDATE_PROC (2,proc);
  1403. SCM_VALIDATE_REST_ARGUMENT (lra);
  1404. switch (SCM_TYP7 (proc))
  1405. {
  1406. default:
  1407. gencase:
  1408. scm_ramapc (ramap, proc, ra0, lra, FUNC_NAME);
  1409. return SCM_UNSPECIFIED;
  1410. case scm_tc7_subr_1:
  1411. scm_ramapc (ramap_1, proc, ra0, lra, FUNC_NAME);
  1412. return SCM_UNSPECIFIED;
  1413. case scm_tc7_subr_2:
  1414. case scm_tc7_subr_2o:
  1415. scm_ramapc (ramap_2o, proc, ra0, lra, FUNC_NAME);
  1416. return SCM_UNSPECIFIED;
  1417. case scm_tc7_cxr:
  1418. if (!SCM_SUBRF (proc))
  1419. goto gencase;
  1420. scm_ramapc (ramap_cxr, proc, ra0, lra, FUNC_NAME);
  1421. return SCM_UNSPECIFIED;
  1422. case scm_tc7_rpsubr:
  1423. {
  1424. ra_iproc *p;
  1425. if (SCM_FALSEP (scm_array_p (ra0, SCM_BOOL_T)))
  1426. goto gencase;
  1427. scm_array_fill_x (ra0, SCM_BOOL_T);
  1428. for (p = ra_rpsubrs; p->name; p++)
  1429. if (SCM_EQ_P (proc, p->sproc))
  1430. {
  1431. while (SCM_NNULLP (lra) && SCM_NNULLP (SCM_CDR (lra)))
  1432. {
  1433. scm_ramapc (p->vproc, SCM_UNDEFINED, ra0, lra, FUNC_NAME);
  1434. lra = SCM_CDR (lra);
  1435. }
  1436. return SCM_UNSPECIFIED;
  1437. }
  1438. while (SCM_NNULLP (lra) && SCM_NNULLP (SCM_CDR (lra)))
  1439. {
  1440. scm_ramapc (ramap_rp, proc, ra0, lra, FUNC_NAME);
  1441. lra = SCM_CDR (lra);
  1442. }
  1443. return SCM_UNSPECIFIED;
  1444. }
  1445. case scm_tc7_asubr:
  1446. if (SCM_NULLP (lra))
  1447. {
  1448. SCM prot, fill = SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED);
  1449. if (SCM_INUMP(fill))
  1450. {
  1451. prot = scm_array_prototype (ra0);
  1452. if (SCM_INEXACTP (prot))
  1453. fill = scm_make_real ((double) SCM_INUM (fill));
  1454. }
  1455. scm_array_fill_x (ra0, fill);
  1456. }
  1457. else
  1458. {
  1459. SCM tail, ra1 = SCM_CAR (lra);
  1460. SCM v0 = (SCM_ARRAYP (ra0) ? SCM_ARRAY_V (ra0) : ra0);
  1461. ra_iproc *p;
  1462. /* Check to see if order might matter.
  1463. This might be an argument for a separate
  1464. SERIAL-ARRAY-MAP! */
  1465. if (SCM_EQ_P (v0, ra1)
  1466. || (SCM_ARRAYP (ra1) && SCM_EQ_P (v0, SCM_ARRAY_V (ra1))))
  1467. if (!SCM_EQ_P (ra0, ra1)
  1468. || (SCM_ARRAYP(ra0) && !SCM_ARRAY_CONTP(ra0)))
  1469. goto gencase;
  1470. for (tail = SCM_CDR (lra); SCM_NNULLP (tail); tail = SCM_CDR (tail))
  1471. {
  1472. ra1 = SCM_CAR (tail);
  1473. if (SCM_EQ_P (v0, ra1)
  1474. || (SCM_ARRAYP (ra1) && SCM_EQ_P (v0, SCM_ARRAY_V (ra1))))
  1475. goto gencase;
  1476. }
  1477. for (p = ra_asubrs; p->name; p++)
  1478. if (SCM_EQ_P (proc, p->sproc))
  1479. {
  1480. if (!SCM_EQ_P (ra0, SCM_CAR (lra)))
  1481. scm_ramapc (scm_array_identity, SCM_UNDEFINED, ra0, scm_cons (SCM_CAR (lra), SCM_EOL), FUNC_NAME);
  1482. lra = SCM_CDR (lra);
  1483. while (1)
  1484. {
  1485. scm_ramapc (p->vproc, SCM_UNDEFINED, ra0, lra, FUNC_NAME);
  1486. if (SCM_IMP (lra) || SCM_IMP (SCM_CDR (lra)))
  1487. return SCM_UNSPECIFIED;
  1488. lra = SCM_CDR (lra);
  1489. }
  1490. }
  1491. scm_ramapc (ramap_2o, proc, ra0, lra, FUNC_NAME);
  1492. lra = SCM_CDR (lra);
  1493. if (SCM_NIMP (lra))
  1494. for (lra = SCM_CDR (lra); SCM_NIMP (lra); lra = SCM_CDR (lra))
  1495. scm_ramapc (ramap_a, proc, ra0, lra, FUNC_NAME);
  1496. }
  1497. return SCM_UNSPECIFIED;
  1498. }
  1499. }
  1500. #undef FUNC_NAME
  1501. static int
  1502. rafe (SCM ra0,SCM proc,SCM ras)
  1503. {
  1504. long i = SCM_ARRAY_DIMS (ra0)->lbnd;
  1505. scm_sizet i0 = SCM_ARRAY_BASE (ra0);
  1506. long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
  1507. long n = SCM_ARRAY_DIMS (ra0)->ubnd;
  1508. ra0 = SCM_ARRAY_V (ra0);
  1509. if (SCM_NULLP (ras))
  1510. for (; i <= n; i++, i0 += inc0)
  1511. scm_apply (proc, scm_cvref (ra0, i0, SCM_UNDEFINED), scm_listofnull);
  1512. else
  1513. {
  1514. SCM ra1 = SCM_CAR (ras);
  1515. SCM args, *ve = &ras;
  1516. scm_sizet k, i1 = SCM_ARRAY_BASE (ra1);
  1517. long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  1518. ra1 = SCM_ARRAY_V (ra1);
  1519. ras = SCM_CDR (ras);
  1520. if (SCM_NULLP(ras))
  1521. ras = scm_nullvect;
  1522. else
  1523. {
  1524. ras = scm_vector (ras);
  1525. ve = SCM_VELTS (ras);
  1526. }
  1527. for (; i <= n; i++, i0 += inc0, i1 += inc1)
  1528. {
  1529. args = SCM_EOL;
  1530. for (k = SCM_LENGTH (ras); k--;)
  1531. args = scm_cons (scm_uniform_vector_ref (ve[k], SCM_MAKINUM (i)), args);
  1532. args = scm_cons2 (scm_cvref (ra0, i0, SCM_UNDEFINED), scm_cvref (ra1, i1, SCM_UNDEFINED), args);
  1533. scm_apply (proc, args, SCM_EOL);
  1534. }
  1535. }
  1536. return 1;
  1537. }
  1538. SCM_DEFINE (scm_array_for_each, "array-for-each", 2, 0, 1,
  1539. (SCM proc, SCM ra0, SCM lra),
  1540. "@var{proc} is applied to each tuple of elements of @var{array0} @dots{}\n"
  1541. "in row-major order. The value returned is unspecified.")
  1542. #define FUNC_NAME s_scm_array_for_each
  1543. {
  1544. SCM_VALIDATE_PROC (1,proc);
  1545. SCM_VALIDATE_REST_ARGUMENT (lra);
  1546. scm_ramapc (rafe, proc, ra0, lra, FUNC_NAME);
  1547. return SCM_UNSPECIFIED;
  1548. }
  1549. #undef FUNC_NAME
  1550. SCM_DEFINE (scm_array_index_map_x, "array-index-map!", 2, 0, 0,
  1551. (SCM ra, SCM proc),
  1552. "applies @var{proc} to the indices of each element of @var{array} in\n"
  1553. "turn, storing the result in the corresponding element. The value\n"
  1554. "returned and the order of application are unspecified.\n\n"
  1555. "One can implement @var{array-indexes} as\n"
  1556. "@example\n"
  1557. "(define (array-indexes array)\n"
  1558. " (let ((ra (apply make-array #f (array-shape array))))\n"
  1559. " (array-index-map! ra (lambda x x))\n"
  1560. " ra))\n"
  1561. "@end example\n"
  1562. "Another example:\n"
  1563. "@example\n"
  1564. "(define (apl:index-generator n)\n"
  1565. " (let ((v (make-uniform-vector n 1)))\n"
  1566. " (array-index-map! v (lambda (i) i))\n"
  1567. " v))\n"
  1568. "@end example")
  1569. #define FUNC_NAME s_scm_array_index_map_x
  1570. {
  1571. scm_sizet i;
  1572. SCM_VALIDATE_NIM (1,ra);
  1573. SCM_VALIDATE_PROC (2,proc);
  1574. switch (SCM_TYP7(ra))
  1575. {
  1576. default:
  1577. badarg:SCM_WTA (1,ra);
  1578. case scm_tc7_vector:
  1579. case scm_tc7_wvect:
  1580. {
  1581. SCM *ve = SCM_VELTS (ra);
  1582. for (i = 0; i < SCM_LENGTH (ra); i++)
  1583. ve[i] = scm_apply (proc, SCM_MAKINUM (i), scm_listofnull);
  1584. return SCM_UNSPECIFIED;
  1585. }
  1586. case scm_tc7_string:
  1587. case scm_tc7_byvect:
  1588. case scm_tc7_bvect:
  1589. case scm_tc7_uvect:
  1590. case scm_tc7_ivect:
  1591. case scm_tc7_svect:
  1592. #ifdef HAVE_LONG_LONGS
  1593. case scm_tc7_llvect:
  1594. #endif
  1595. case scm_tc7_fvect:
  1596. case scm_tc7_dvect:
  1597. case scm_tc7_cvect:
  1598. for (i = 0; i < SCM_LENGTH (ra); i++)
  1599. scm_array_set_x (ra, scm_apply (proc, SCM_MAKINUM (i), scm_listofnull),
  1600. SCM_MAKINUM (i));
  1601. return SCM_UNSPECIFIED;
  1602. case scm_tc7_smob:
  1603. SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
  1604. {
  1605. SCM args = SCM_EOL;
  1606. SCM inds = scm_make_uve (SCM_ARRAY_NDIM (ra), SCM_MAKINUM (-1L));
  1607. long *vinds = (long *) SCM_VELTS (inds);
  1608. int j, k, kmax = SCM_ARRAY_NDIM (ra) - 1;
  1609. if (kmax < 0)
  1610. return scm_array_set_x (ra, scm_apply(proc, SCM_EOL, SCM_EOL),
  1611. SCM_EOL);
  1612. for (k = 0; k <= kmax; k++)
  1613. vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd;
  1614. k = kmax;
  1615. do
  1616. {
  1617. if (k == kmax)
  1618. {
  1619. vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd;
  1620. i = cind (ra, inds);
  1621. for (; vinds[k] <= SCM_ARRAY_DIMS (ra)[k].ubnd; vinds[k]++)
  1622. {
  1623. for (j = kmax + 1, args = SCM_EOL; j--;)
  1624. args = scm_cons (SCM_MAKINUM (vinds[j]), args);
  1625. scm_array_set_x (SCM_ARRAY_V (ra),
  1626. scm_apply (proc, args, SCM_EOL),
  1627. SCM_MAKINUM (i));
  1628. i += SCM_ARRAY_DIMS (ra)[k].inc;
  1629. }
  1630. k--;
  1631. continue;
  1632. }
  1633. if (vinds[k] < SCM_ARRAY_DIMS (ra)[k].ubnd)
  1634. {
  1635. vinds[k]++;
  1636. k++;
  1637. continue;
  1638. }
  1639. vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd - 1;
  1640. k--;
  1641. }
  1642. while (k >= 0);
  1643. return SCM_UNSPECIFIED;
  1644. }
  1645. }
  1646. }
  1647. #undef FUNC_NAME
  1648. static int
  1649. raeql_1 (SCM ra0,SCM as_equal,SCM ra1)
  1650. {
  1651. SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
  1652. scm_sizet i0 = 0, i1 = 0;
  1653. long inc0 = 1, inc1 = 1;
  1654. scm_sizet n = SCM_LENGTH (ra0);
  1655. ra1 = SCM_CAR (ra1);
  1656. if (SCM_ARRAYP(ra0))
  1657. {
  1658. n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
  1659. i0 = SCM_ARRAY_BASE (ra0);
  1660. inc0 = SCM_ARRAY_DIMS (ra0)->inc;
  1661. ra0 = SCM_ARRAY_V (ra0);
  1662. }
  1663. if (SCM_ARRAYP (ra1))
  1664. {
  1665. i1 = SCM_ARRAY_BASE (ra1);
  1666. inc1 = SCM_ARRAY_DIMS (ra1)->inc;
  1667. ra1 = SCM_ARRAY_V (ra1);
  1668. }
  1669. switch (SCM_TYP7 (ra0))
  1670. {
  1671. case scm_tc7_vector:
  1672. case scm_tc7_wvect:
  1673. default:
  1674. for (; n--; i0 += inc0, i1 += inc1)
  1675. {
  1676. if (SCM_FALSEP (as_equal))
  1677. {
  1678. if (SCM_FALSEP (scm_array_equal_p (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1))))
  1679. return 0;
  1680. }
  1681. else if (SCM_FALSEP (scm_equal_p (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1))))
  1682. return 0;
  1683. }
  1684. return 1;
  1685. case scm_tc7_string:
  1686. case scm_tc7_byvect:
  1687. {
  1688. char *v0 = SCM_CHARS (ra0) + i0;
  1689. char *v1 = SCM_CHARS (ra1) + i1;
  1690. for (; n--; v0 += inc0, v1 += inc1)
  1691. if (*v0 != *v1)
  1692. return 0;
  1693. return 1;
  1694. }
  1695. case scm_tc7_bvect:
  1696. for (; n--; i0 += inc0, i1 += inc1)
  1697. if (SCM_BITVEC_REF (ra0, i0) != SCM_BITVEC_REF (ra1, i1))
  1698. return 0;
  1699. return 1;
  1700. case scm_tc7_uvect:
  1701. case scm_tc7_ivect:
  1702. {
  1703. long *v0 = (long *) SCM_VELTS (ra0) + i0;
  1704. long *v1 = (long *) SCM_VELTS (ra1) + i1;
  1705. for (; n--; v0 += inc0, v1 += inc1)
  1706. if (*v0 != *v1)
  1707. return 0;
  1708. return 1;
  1709. }
  1710. case scm_tc7_svect:
  1711. {
  1712. short *v0 = (short *) SCM_VELTS (ra0) + i0;
  1713. short *v1 = (short *) SCM_VELTS (ra1) + i1;
  1714. for (; n--; v0 += inc0, v1 += inc1)
  1715. if (*v0 != *v1)
  1716. return 0;
  1717. return 1;
  1718. }
  1719. #ifdef HAVE_LONG_LONGS
  1720. case scm_tc7_llvect:
  1721. {
  1722. long long *v0 = (long long *) SCM_VELTS (ra0) + i0;
  1723. long long *v1 = (long long *) SCM_VELTS (ra1) + i1;
  1724. for (; n--; v0 += inc0, v1 += inc1)
  1725. if (*v0 != *v1)
  1726. return 0;
  1727. return 1;
  1728. }
  1729. #endif
  1730. case scm_tc7_fvect:
  1731. {
  1732. float *v0 = (float *) SCM_VELTS (ra0) + i0;
  1733. float *v1 = (float *) SCM_VELTS (ra1) + i1;
  1734. for (; n--; v0 += inc0, v1 += inc1)
  1735. if (*v0 != *v1)
  1736. return 0;
  1737. return 1;
  1738. }
  1739. case scm_tc7_dvect:
  1740. {
  1741. double *v0 = (double *) SCM_VELTS (ra0) + i0;
  1742. double *v1 = (double *) SCM_VELTS (ra1) + i1;
  1743. for (; n--; v0 += inc0, v1 += inc1)
  1744. if (*v0 != *v1)
  1745. return 0;
  1746. return 1;
  1747. }
  1748. case scm_tc7_cvect:
  1749. {
  1750. double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0) + i0;
  1751. double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1) + i1;
  1752. for (; n--; v0 += inc0, v1 += inc1)
  1753. {
  1754. if ((*v0)[0] != (*v1)[0])
  1755. return 0;
  1756. if ((*v0)[1] != (*v1)[1])
  1757. return 0;
  1758. }
  1759. return 1;
  1760. }
  1761. }
  1762. }
  1763. static int
  1764. raeql (SCM ra0,SCM as_equal,SCM ra1)
  1765. {
  1766. SCM v0 = ra0, v1 = ra1;
  1767. scm_array_dim dim0, dim1;
  1768. scm_array_dim *s0 = &dim0, *s1 = &dim1;
  1769. scm_sizet bas0 = 0, bas1 = 0;
  1770. int k, unroll = 1, vlen = 1, ndim = 1;
  1771. if (SCM_ARRAYP (ra0))
  1772. {
  1773. ndim = SCM_ARRAY_NDIM (ra0);
  1774. s0 = SCM_ARRAY_DIMS (ra0);
  1775. bas0 = SCM_ARRAY_BASE (ra0);
  1776. v0 = SCM_ARRAY_V (ra0);
  1777. }
  1778. else
  1779. {
  1780. s0->inc = 1;
  1781. s0->lbnd = 0;
  1782. s0->ubnd = SCM_LENGTH (v0) - 1;
  1783. unroll = 0;
  1784. }
  1785. if (SCM_ARRAYP (ra1))
  1786. {
  1787. if (ndim != SCM_ARRAY_NDIM (ra1))
  1788. return 0;
  1789. s1 = SCM_ARRAY_DIMS (ra1);
  1790. bas1 = SCM_ARRAY_BASE (ra1);
  1791. v1 = SCM_ARRAY_V (ra1);
  1792. }
  1793. else
  1794. {
  1795. /*
  1796. Huh ? Schizophrenic return type. --hwn
  1797. */
  1798. if (1 != ndim)
  1799. return 0;
  1800. s1->inc = 1;
  1801. s1->lbnd = 0;
  1802. s1->ubnd = SCM_LENGTH (v1) - 1;
  1803. unroll = 0;
  1804. }
  1805. if (SCM_TYP7 (v0) != SCM_TYP7 (v1))
  1806. return 0;
  1807. for (k = ndim; k--;)
  1808. {
  1809. if (s0[k].lbnd != s1[k].lbnd || s0[k].ubnd != s1[k].ubnd)
  1810. return 0;
  1811. if (unroll)
  1812. {
  1813. unroll = (s0[k].inc == s1[k].inc);
  1814. vlen *= s0[k].ubnd - s1[k].lbnd + 1;
  1815. }
  1816. }
  1817. if (unroll && bas0 == bas1 && SCM_EQ_P (v0, v1))
  1818. return 1;
  1819. return scm_ramapc (raeql_1, as_equal, ra0, scm_cons (ra1, SCM_EOL), "");
  1820. }
  1821. SCM
  1822. scm_raequal (SCM ra0, SCM ra1)
  1823. {
  1824. return SCM_BOOL(raeql (ra0, SCM_BOOL_T, ra1));
  1825. }
  1826. #if 0
  1827. /* GJB:FIXME:: Why not use SCM_DEFINE1 for array-equal? */
  1828. SCM_DEFINE1 (scm_array_equal_p, "array-equal?", scm_tc7_rpsubr,
  1829. (SCM ra0, SCM ra1),
  1830. "Returns @code{#t} iff all arguments are arrays with the same shape, the\n"
  1831. "same type, and have corresponding elements which are either\n"
  1832. "@code{equal?} or @code{array-equal?}. This function differs from\n"
  1833. "@code{equal?} in that a one dimensional shared array may be\n"
  1834. "@var{array-equal?} but not @var{equal?} to a vector or uniform vector.")
  1835. #define FUNC_NAME s_scm_array_equal_p
  1836. {
  1837. }
  1838. #undef FUNC_NAME
  1839. #endif
  1840. static char s_array_equal_p[] = "array-equal?";
  1841. SCM
  1842. scm_array_equal_p (SCM ra0, SCM ra1)
  1843. {
  1844. if (SCM_IMP (ra0) || SCM_IMP (ra1))
  1845. callequal:return scm_equal_p (ra0, ra1);
  1846. switch (SCM_TYP7(ra0))
  1847. {
  1848. default:
  1849. goto callequal;
  1850. case scm_tc7_bvect:
  1851. case scm_tc7_string:
  1852. case scm_tc7_byvect:
  1853. case scm_tc7_uvect:
  1854. case scm_tc7_ivect:
  1855. case scm_tc7_fvect:
  1856. case scm_tc7_dvect:
  1857. case scm_tc7_cvect:
  1858. case scm_tc7_vector:
  1859. case scm_tc7_wvect:
  1860. break;
  1861. case scm_tc7_smob:
  1862. if (!SCM_ARRAYP (ra0))
  1863. goto callequal;
  1864. }
  1865. switch (SCM_TYP7 (ra1))
  1866. {
  1867. default:
  1868. goto callequal;
  1869. case scm_tc7_bvect:
  1870. case scm_tc7_string:
  1871. case scm_tc7_byvect:
  1872. case scm_tc7_uvect:
  1873. case scm_tc7_ivect:
  1874. case scm_tc7_fvect:
  1875. case scm_tc7_dvect:
  1876. case scm_tc7_cvect:
  1877. case scm_tc7_vector:
  1878. case scm_tc7_wvect:
  1879. break;
  1880. case scm_tc7_smob:
  1881. if (!SCM_ARRAYP (ra1))
  1882. goto callequal;
  1883. }
  1884. return SCM_BOOL(raeql (ra0, SCM_BOOL_F, ra1));
  1885. }
  1886. static void
  1887. init_raprocs (ra_iproc *subra)
  1888. {
  1889. for (; subra->name; subra++)
  1890. subra->sproc = SCM_CDR (scm_intern (subra->name, strlen (subra->name)));
  1891. }
  1892. void
  1893. scm_init_ramap ()
  1894. {
  1895. init_raprocs (ra_rpsubrs);
  1896. init_raprocs (ra_asubrs);
  1897. scm_make_subr (s_array_equal_p, scm_tc7_rpsubr, scm_array_equal_p);
  1898. scm_smobs[0x0ff & (scm_tc16_array >> 8)].equalp = scm_raequal;
  1899. #include "libguile/ramap.x"
  1900. scm_add_feature (s_scm_array_for_each);
  1901. }
  1902. /*
  1903. Local Variables:
  1904. c-file-style: "gnu"
  1905. End:
  1906. */