* __scm.h, alist.c, alist.h, append.c, append.h, appinit.c,
[bpt/guile.git] / libguile / ramap.c
CommitLineData
0f2d19dd
JB
1/* Copyright (C) 1996 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, 675 Mass Ave, Cambridge, MA 02139, USA.
16 *
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
19 *
20 * The exception is that, if you link the GUILE library with other files
21 * to produce an executable, this does not by itself cause the
22 * resulting executable to be covered by the GNU General Public License.
23 * Your use of that executable is in no way restricted on account of
24 * linking the GUILE library code into it.
25 *
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
28 *
29 * This exception applies only to the code released by the
30 * Free Software Foundation under the name GUILE. If you copy
31 * code from other Free Software Foundation releases into a copy of
32 * GUILE, as the General Public License permits, the exception does
33 * not apply to the code that you add in this way. To avoid misleading
34 * anyone as to the status of such modified files, you must delete
35 * this exception notice from them.
36 *
37 * If you write modifications of your own for GUILE, it is your choice
38 * whether to permit this exception to apply to your modifications.
39 * If you do not wish that, delete this exception notice.
40 */
41\f
42
43
44\f
45
46#include <stdio.h>
47#include "_scm.h"
20e6290e
JB
48#include "unif.h"
49#include "smob.h"
50#include "chars.h"
51#include "eq.h"
52#include "eval.h"
53#include "feature.h"
0f2d19dd 54
20e6290e 55#include "ramap.h"
0f2d19dd
JB
56\f
57
58#ifdef ARRAYS
59
60typedef struct
61{
62 char *name;
63 SCM sproc;
64 int (*vproc) ();
65} ra_iproc;
66
67static ra_iproc ra_rpsubrs[];
68static ra_iproc ra_asubrs[];
69
70#define BVE_REF(a, i) ((SCM_VELTS(a)[(i)/SCM_LONG_BIT] & (1L<<((i)%SCM_LONG_BIT))) ? 1 : 0)
71#define BVE_SET(a, i) (SCM_VELTS(a)[(i)/SCM_LONG_BIT] |= (1L<<((i)%SCM_LONG_BIT)))
72#define BVE_CLR(a, i) (SCM_VELTS(a)[(i)/SCM_LONG_BIT] &= ~(1L<<((i)%SCM_LONG_BIT)))
73
74/* Fast, recycling scm_vector ref */
75#define RVREF(ra, i, e) (e = scm_cvref(ra, i, e))
76
77/* #define RVREF(ra, i, e) (scm_cvref(ra, i, SCM_UNDEFINED)) to turn off */
78
79/* IVDEP means "ignore scm_vector dependencies", meaning we guarantee that
80 elements of scm_vector operands are not aliased */
81#ifdef _UNICOS
82#define IVDEP(test, line) if (test) {_Pragma("ivdep"); line} else {line}
83#else
84#define IVDEP(test, line) line
85#endif
86
87\f
88
89/* inds must be a uvect or ivect, no check. */
90
91#ifdef __STDC__
92static scm_sizet
93cind (SCM ra, SCM inds)
94#else
95static scm_sizet
96cind (ra, inds)
97 SCM ra;
98 SCM inds;
99#endif
100{
101 scm_sizet i;
102 int k;
103 long *ve = SCM_VELTS (inds);
104 if (!SCM_ARRAYP (ra))
105 return *ve;
106 i = SCM_ARRAY_BASE (ra);
107 for (k = 0; k < SCM_ARRAY_NDIM (ra); k++)
108 i += (ve[k] - SCM_ARRAY_DIMS (ra)[k].lbnd) * SCM_ARRAY_DIMS (ra)[k].inc;
109 return i;
110}
111
112
113/* Checker for scm_array mapping functions:
114 return values: 4 --> shapes, increments, and bases are the same;
115 3 --> shapes and increments are the same;
116 2 --> shapes are the same;
117 1 --> ras are at least as big as ra0;
118 0 --> no match.
119 */
120#ifdef __STDC__
121int
122scm_ra_matchp (SCM ra0, SCM ras)
123#else
124int
125scm_ra_matchp (ra0, ras)
126 SCM ra0;
127 SCM ras;
128#endif
129{
130 SCM ra1;
131 scm_array_dim dims;
132 scm_array_dim *s0 = &dims;
133 scm_array_dim *s1;
134 scm_sizet bas0 = 0;
135 int i, ndim = 1;
136 int exact = 2 /* 4 */ ; /* Don't care about values >2 (yet?) */
137 if SCM_IMP
138 (ra0) return 0;
139 switch (SCM_TYP7 (ra0))
140 {
141 default:
142 return 0;
143 case scm_tc7_vector:
144 case scm_tc7_string:
145 case scm_tc7_bvect:
146 case scm_tc7_uvect:
147 case scm_tc7_ivect:
148 case scm_tc7_fvect:
149 case scm_tc7_dvect:
150 case scm_tc7_cvect:
151 s0->lbnd = 0;
152 s0->inc = 1;
153 s0->ubnd = (long) SCM_LENGTH (ra0) - 1;
154 break;
155 case scm_tc7_smob:
156 if (!SCM_ARRAYP (ra0))
157 return 0;
158 ndim = SCM_ARRAY_NDIM (ra0);
159 s0 = SCM_ARRAY_DIMS (ra0);
160 bas0 = SCM_ARRAY_BASE (ra0);
161 break;
162 }
163 while SCM_NIMP
164 (ras)
165 {
166 ra1 = SCM_CAR (ras);
167 if SCM_IMP
168 (ra1) return 0;
169 switch SCM_TYP7
170 (ra1)
171 {
172 default:
173 return 0;
174 case scm_tc7_vector:
175 case scm_tc7_string:
176 case scm_tc7_bvect:
177 case scm_tc7_uvect:
178 case scm_tc7_ivect:
179 case scm_tc7_fvect:
180 case scm_tc7_dvect:
181 case scm_tc7_cvect:
182 if (1 != ndim)
183 return 0;
184 switch (exact)
185 {
186 case 4:
187 if (0 != bas0)
188 exact = 3;
189 case 3:
190 if (1 != s0->inc)
191 exact = 2;
192 case 2:
193 if ((0 == s0->lbnd) && (s0->ubnd == SCM_LENGTH (ra1) - 1))
194 break;
195 exact = 1;
196 case 1:
197 if (s0->lbnd < 0 || s0->ubnd >= SCM_LENGTH (ra1))
198 return 0;
199 }
200 break;
201 case scm_tc7_smob:
202 if (!SCM_ARRAYP (ra1) || ndim != SCM_ARRAY_NDIM (ra1))
203 return 0;
204 s1 = SCM_ARRAY_DIMS (ra1);
205 if (bas0 != SCM_ARRAY_BASE (ra1))
206 exact = 3;
207 for (i = 0; i < ndim; i++)
208 switch (exact)
209 {
210 case 4:
211 case 3:
212 if (s0[i].inc != s1[i].inc)
213 exact = 2;
214 case 2:
215 if (s0[i].lbnd == s1[i].lbnd && s0[i].ubnd == s1[i].ubnd)
216 break;
217 exact = 1;
218 default:
219 if (s0[i].lbnd < s1[i].lbnd || s0[i].ubnd > s1[i].ubnd)
220 return (s0[i].lbnd <= s0[i].ubnd ? 0 : 1);
221 }
222 break;
223 }
224 ras = SCM_CDR (ras);
225 }
226 return exact;
227}
228
229static char s_ra_mismatch[] = "array shape mismatch";
230
231#ifdef __STDC__
232int
233scm_ramapc (int (*cproc) (), SCM data, SCM ra0, SCM lra, char *what)
234#else
235int
236scm_ramapc (cproc, data, ra0, lra, what)
237 int (*cproc) ();
238 SCM data;
239 SCM ra0;
240 SCM lra;
241 char *what;
242#endif
243{
244 SCM inds, z;
245 SCM vra0, ra1, vra1;
246 SCM lvra, *plvra;
247 long *vinds;
248 int k, kmax;
249 switch (scm_ra_matchp (ra0, lra))
250 {
251 default:
252 case 0:
253 scm_wta (ra0, s_ra_mismatch, what);
254 case 2:
255 case 3:
256 case 4: /* Try unrolling arrays */
257 kmax = (SCM_ARRAYP (ra0) ? SCM_ARRAY_NDIM (ra0) - 1 : 0);
258 if (kmax < 0)
259 goto gencase;
260 vra0 = scm_array_contents (ra0, SCM_UNDEFINED);
261 if SCM_IMP
262 (vra0) goto gencase;
263 if (!SCM_ARRAYP (vra0))
264 {
265 vra1 = scm_make_ra (1);
266 SCM_ARRAY_BASE (vra1) = 0;
267 SCM_ARRAY_DIMS (vra1)->lbnd = 0;
268 SCM_ARRAY_DIMS (vra1)->ubnd = SCM_LENGTH (vra0) - 1;
269 SCM_ARRAY_DIMS (vra1)->inc = 1;
270 SCM_ARRAY_V (vra1) = vra0;
271 vra0 = vra1;
272 }
273 lvra = SCM_EOL;
274 plvra = &lvra;
275 for (z = lra; SCM_NIMP (z); z = SCM_CDR (z))
276 {
277 ra1 = SCM_CAR (z);
278 vra1 = scm_make_ra (1);
279 SCM_ARRAY_DIMS (vra1)->lbnd = SCM_ARRAY_DIMS (vra0)->lbnd;
280 SCM_ARRAY_DIMS (vra1)->ubnd = SCM_ARRAY_DIMS (vra0)->ubnd;
281 if (!SCM_ARRAYP (ra1))
282 {
283 SCM_ARRAY_BASE (vra1) = 0;
284 SCM_ARRAY_DIMS (vra1)->inc = 1;
285 SCM_ARRAY_V (vra1) = ra1;
286 }
287 else if (!SCM_ARRAY_CONTP (ra1))
288 goto gencase;
289 else
290 {
291 SCM_ARRAY_BASE (vra1) = SCM_ARRAY_BASE (ra1);
292 SCM_ARRAY_DIMS (vra1)->inc = SCM_ARRAY_DIMS (ra1)[kmax].inc;
293 SCM_ARRAY_V (vra1) = SCM_ARRAY_V (ra1);
294 }
295 *plvra = scm_cons (vra1, SCM_EOL);
296 plvra = &SCM_CDR (*plvra);
297 }
298 return (SCM_UNBNDP (data) ? cproc(vra0, lvra) : cproc(vra0, data, lvra));
299 case 1:
300 gencase: /* Have to loop over all dimensions. */
301 vra0 = scm_make_ra (1);
302 if SCM_ARRAYP
303 (ra0)
304 {
305 kmax = SCM_ARRAY_NDIM (ra0) - 1;
306 if (kmax < 0)
307 {
308 SCM_ARRAY_DIMS (vra0)->lbnd = 0;
309 SCM_ARRAY_DIMS (vra0)->ubnd = 0;
310 SCM_ARRAY_DIMS (vra0)->inc = 1;
311 }
312 else
313 {
314 SCM_ARRAY_DIMS (vra0)->lbnd = SCM_ARRAY_DIMS (ra0)[kmax].lbnd;
315 SCM_ARRAY_DIMS (vra0)->ubnd = SCM_ARRAY_DIMS (ra0)[kmax].ubnd;
316 SCM_ARRAY_DIMS (vra0)->inc = SCM_ARRAY_DIMS (ra0)[kmax].inc;
317 }
318 SCM_ARRAY_BASE (vra0) = SCM_ARRAY_BASE (ra0);
319 SCM_ARRAY_V (vra0) = SCM_ARRAY_V (ra0);
320 }
321 else
322 {
323 kmax = 0;
324 SCM_ARRAY_DIMS (vra0)->lbnd = 0;
325 SCM_ARRAY_DIMS (vra0)->ubnd = SCM_LENGTH (ra0) - 1;
326 SCM_ARRAY_DIMS (vra0)->inc = 1;
327 SCM_ARRAY_BASE (vra0) = 0;
328 SCM_ARRAY_V (vra0) = ra0;
329 ra0 = vra0;
330 }
331 lvra = SCM_EOL;
332 plvra = &lvra;
333 for (z = lra; SCM_NIMP (z); z = SCM_CDR (z))
334 {
335 ra1 = SCM_CAR (z);
336 vra1 = scm_make_ra (1);
337 SCM_ARRAY_DIMS (vra1)->lbnd = SCM_ARRAY_DIMS (vra0)->lbnd;
338 SCM_ARRAY_DIMS (vra1)->ubnd = SCM_ARRAY_DIMS (vra0)->ubnd;
339 if SCM_ARRAYP
340 (ra1)
341 {
342 if (kmax >= 0)
343 SCM_ARRAY_DIMS (vra1)->inc = SCM_ARRAY_DIMS (ra1)[kmax].inc;
344 SCM_ARRAY_V (vra1) = SCM_ARRAY_V (ra1);
345 }
346 else
347 {
348 SCM_ARRAY_DIMS (vra1)->inc = 1;
349 SCM_ARRAY_V (vra1) = ra1;
350 }
351 *plvra = scm_cons (vra1, SCM_EOL);
352 plvra = &SCM_CDR (*plvra);
353 }
354 inds = scm_make_uve (SCM_ARRAY_NDIM (ra0), SCM_MAKINUM (-1L));
355 vinds = (long *) SCM_VELTS (inds);
356 for (k = 0; k <= kmax; k++)
357 vinds[k] = SCM_ARRAY_DIMS (ra0)[k].lbnd;
358 k = kmax;
359 do
360 {
361 if (k == kmax)
362 {
363 SCM y = lra;
364 SCM_ARRAY_BASE (vra0) = cind (ra0, inds);
365 for (z = lvra; SCM_NIMP (z); z = SCM_CDR (z), y = SCM_CDR (y))
366 SCM_ARRAY_BASE (SCM_CAR (z)) = cind (SCM_CAR (y), inds);
367 if (0 == (SCM_UNBNDP (data) ? cproc(vra0, lvra) : cproc(vra0, data, lvra)))
368 return 0;
369 k--;
370 continue;
371 }
372 if (vinds[k] < SCM_ARRAY_DIMS (ra0)[k].ubnd)
373 {
374 vinds[k]++;
375 k++;
376 continue;
377 }
378 vinds[k] = SCM_ARRAY_DIMS (ra0)[k].lbnd - 1;
379 k--;
380 }
381 while (k >= 0);
382 return 1;
383 }
384}
385
386
387static char s_array_fill_x[];
388#ifdef __STDC__
389int
390scm_array_fill_int (SCM ra, SCM fill, SCM ignore)
391#else
392int
393scm_array_fill_int (ra, fill, ignore)
394 SCM ra;
395 SCM fill;
396 SCM ignore;
397#endif
398{
399 scm_sizet i, n = SCM_ARRAY_DIMS (ra)->ubnd - SCM_ARRAY_DIMS (ra)->lbnd + 1;
400 long inc = SCM_ARRAY_DIMS (ra)->inc;
401 scm_sizet base = SCM_ARRAY_BASE (ra);
402 ra = SCM_ARRAY_V (ra);
403 switch SCM_TYP7
404 (ra)
405 {
406 default:
407 for (i = base; n--; i += inc)
408 scm_array_set_x (ra, fill, SCM_MAKINUM (i));
409 break;
410 case scm_tc7_vector:
411 for (i = base; n--; i += inc)
412 SCM_VELTS (ra)[i] = fill;
413 break;
414 case scm_tc7_string:
415 SCM_ASRTGO (SCM_ICHRP (fill), badarg2);
416 for (i = base; n--; i += inc)
417 SCM_CHARS (ra)[i] = SCM_ICHR (fill);
418 break;
419 case scm_tc7_bvect:
420 {
421 long *ve = (long *) SCM_VELTS (ra);
422 if (1 == inc && (n >= SCM_LONG_BIT || n == SCM_LENGTH (ra)))
423 {
424 i = base / SCM_LONG_BIT;
425 if (SCM_BOOL_F == fill)
426 {
427 if (base % SCM_LONG_BIT) /* leading partial word */
428 ve[i++] &= ~(~0L << (base % SCM_LONG_BIT));
429 for (; i < (base + n) / SCM_LONG_BIT; i++)
430 ve[i] = 0L;
431 if ((base + n) % SCM_LONG_BIT) /* trailing partial word */
432 ve[i] &= (~0L << ((base + n) % SCM_LONG_BIT));
433 }
434 else if (SCM_BOOL_T == fill)
435 {
436 if (base % SCM_LONG_BIT)
437 ve[i++] |= ~0L << (base % SCM_LONG_BIT);
438 for (; i < (base + n) / SCM_LONG_BIT; i++)
439 ve[i] = ~0L;
440 if ((base + n) % SCM_LONG_BIT)
441 ve[i] |= ~(~0L << ((base + n) % SCM_LONG_BIT));
442 }
443 else
444 badarg2:scm_wta (fill, (char *) SCM_ARG2, s_array_fill_x);
445 }
446 else
447 {
448 if (SCM_BOOL_F == fill)
449 for (i = base; n--; i += inc)
450 ve[i / SCM_LONG_BIT] &= ~(1L << (i % SCM_LONG_BIT));
451 else if (SCM_BOOL_T == fill)
452 for (i = base; n--; i += inc)
453 ve[i / SCM_LONG_BIT] |= (1L << (i % SCM_LONG_BIT));
454 else
455 goto badarg2;
456 }
457 break;
458 }
459 case scm_tc7_uvect:
460 SCM_ASRTGO (0 <= SCM_INUM (fill), badarg2);
461 case scm_tc7_ivect:
462 SCM_ASRTGO (SCM_INUMP (fill), badarg2);
463 {
464 long f = SCM_INUM (fill), *ve = (long *) SCM_VELTS (ra);
465 for (i = base; n--; i += inc)
466 ve[i] = f;
467 break;
468 }
469#ifdef SCM_FLOATS
470#ifdef SCM_SINGLES
471 case scm_tc7_fvect:
472 {
473 float f, *ve = (float *) SCM_VELTS (ra);
474 SCM_ASRTGO (SCM_NIMP (fill) && SCM_REALP (fill), badarg2);
475 f = SCM_REALPART (fill);
476 for (i = base; n--; i += inc)
477 ve[i] = f;
478 break;
479 }
480#endif /* SCM_SINGLES */
481 case scm_tc7_dvect:
482 {
483 double f, *ve = (double *) SCM_VELTS (ra);
484 SCM_ASRTGO (SCM_NIMP (fill) && SCM_REALP (fill), badarg2);
485 f = SCM_REALPART (fill);
486 for (i = base; n--; i += inc)
487 ve[i] = f;
488 break;
489 }
490 case scm_tc7_cvect:
491 {
492 double fr, fi;
493 double (*ve)[2] = (double (*)[2]) SCM_VELTS (ra);
494 SCM_ASRTGO (SCM_NIMP (fill) && SCM_INEXP (fill), badarg2);
495 fr = SCM_REALPART (fill);
496 fi = (SCM_CPLXP (fill) ? SCM_IMAG (fill) : 0.0);
497 for (i = base; n--; i += inc)
498 {
499 ve[i][0] = fr;
500 ve[i][1] = fi;
501 }
502 break;
503 }
504#endif /* SCM_FLOATS */
505 }
506 return 1;
507}
508
509SCM_PROC(s_array_fill_x, "array-fill!", 2, 0, 0, scm_array_fill_x);
510#ifdef __STDC__
511SCM
512scm_array_fill_x (SCM ra, SCM fill)
513#else
514SCM
515scm_array_fill_x (ra, fill)
516 SCM ra;
517 SCM fill;
518#endif
519{
520 scm_ramapc (scm_array_fill_int, fill, ra, SCM_EOL, s_array_fill_x);
521 return SCM_UNSPECIFIED;
522}
523
524
525
526#ifdef __STDC__
527static int
528racp (SCM dst, SCM src)
529#else
530static int
531racp (src, dst)
532 SCM dst;
533 SCM src;
534#endif
535{
536 long n = (SCM_ARRAY_DIMS (src)->ubnd - SCM_ARRAY_DIMS (src)->lbnd + 1);
537 long inc_d, inc_s = SCM_ARRAY_DIMS (src)->inc;
538 scm_sizet i_d, i_s = SCM_ARRAY_BASE (src);
539 dst = SCM_CAR (dst);
540 inc_d = SCM_ARRAY_DIMS (dst)->inc;
541 i_d = SCM_ARRAY_BASE (dst);
542 src = SCM_ARRAY_V (src);
543 dst = SCM_ARRAY_V (dst);
544 switch SCM_TYP7
545 (dst)
546 {
547 default:
548 gencase: case scm_tc7_vector:
549 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
550 scm_array_set_x (dst, scm_cvref (src, i_s, SCM_UNDEFINED), SCM_MAKINUM (i_d));
551 break;
552 case scm_tc7_string:
553 if (scm_tc7_string != SCM_TYP7 (dst))
554 goto gencase;
555 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
556 SCM_CHARS (dst)[i_d] = SCM_CHARS (src)[i_s];
557 break;
558 case scm_tc7_bvect:
559 if (scm_tc7_bvect != SCM_TYP7 (dst))
560 goto gencase;
561 if (1 == inc_d && 1 == inc_s && i_s % SCM_LONG_BIT == i_d % SCM_LONG_BIT && n >= SCM_LONG_BIT)
562 {
563 long *sv = (long *) SCM_VELTS (src);
564 long *dv = (long *) SCM_VELTS (dst);
565 sv += i_s / SCM_LONG_BIT;
566 dv += i_d / SCM_LONG_BIT;
567 if (i_s % SCM_LONG_BIT)
568 { /* leading partial word */
569 *dv = (*dv & ~(~0L << (i_s % SCM_LONG_BIT))) | (*sv & (~0L << (i_s % SCM_LONG_BIT)));
570 dv++;
571 sv++;
572 n -= SCM_LONG_BIT - (i_s % SCM_LONG_BIT);
573 }
574 IVDEP (src != dst,
575 for (; n >= SCM_LONG_BIT; n -= SCM_LONG_BIT, sv++, dv++)
576 * dv = *sv;)
577 if (n) /* trailing partial word */
578 *dv = (*dv & (~0L << n)) | (*sv & ~(~0L << n));
579 }
580 else
581 {
582 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
583 if (SCM_VELTS (src)[i_s / SCM_LONG_BIT] & (1L << (i_s % SCM_LONG_BIT)))
584 SCM_VELTS (dst)[i_d / SCM_LONG_BIT] |= (1L << (i_d % SCM_LONG_BIT));
585 else
586 SCM_VELTS (dst)[i_d / SCM_LONG_BIT] &= ~(1L << (i_d % SCM_LONG_BIT));
587 }
588 break;
589 case scm_tc7_uvect:
590 if (scm_tc7_uvect != SCM_TYP7 (src))
591 goto gencase;
592 else
593 {
594 long *d = (long *) SCM_VELTS (dst), *s = (long *) SCM_VELTS (src);
595 IVDEP (src != dst,
596 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
597 d[i_d] = s[i_s];)
598 break;
599 }
600 case scm_tc7_ivect:
601 if (scm_tc7_uvect != SCM_TYP7 (src) && scm_tc7_ivect != SCM_TYP7 (src))
602 goto gencase;
603 else
604 {
605 long *d = (long *) SCM_VELTS (dst), *s = (long *) SCM_VELTS (src);
606 IVDEP (src != dst,
607 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
608 d[i_d] = s[i_s];)
609 break;
610 }
611#ifdef SCM_FLOATS
612#ifdef SCM_SINGLES
613 case scm_tc7_fvect:
614 {
615 float *d = (float *) SCM_VELTS (dst);
616 float *s = (float *) SCM_VELTS (src);
617 switch SCM_TYP7
618 (src)
619 {
620 default:
621 goto gencase;
622 case scm_tc7_ivect:
623 case scm_tc7_uvect:
624 IVDEP (src != dst,
625 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
626 d[i_d] = ((long *) s)[i_s];)
627 break;
628 case scm_tc7_fvect:
629 IVDEP (src != dst,
630 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
631 d[i_d] = s[i_s];)
632 break;
633 case scm_tc7_dvect:
634 IVDEP (src != dst,
635 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
636 d[i_d] = ((double *) s)[i_s];)
637 break;
638 }
639 break;
640 }
641#endif /* SCM_SINGLES */
642 case scm_tc7_dvect:
643 {
644 double *d = (double *) SCM_VELTS (dst);
645 double *s = (double *) SCM_VELTS (src);
646 switch SCM_TYP7
647 (src)
648 {
649 default:
650 goto gencase;
651 case scm_tc7_ivect:
652 case scm_tc7_uvect:
653 IVDEP (src != dst,
654 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
655 d[i_d] = ((long *) s)[i_s];)
656 break;
657 case scm_tc7_fvect:
658 IVDEP (src != dst,
659 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
660 d[i_d] = ((float *) s)[i_s];)
661 break;
662 case scm_tc7_dvect:
663 IVDEP (src != dst,
664 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
665 d[i_d] = s[i_s];)
666 break;
667 }
668 break;
669 }
670 case scm_tc7_cvect:
671 {
672 double (*d)[2] = (double (*)[2]) SCM_VELTS (dst);
673 double (*s)[2] = (double (*)[2]) SCM_VELTS (src);
674 switch SCM_TYP7
675 (src)
676 {
677 default:
678 goto gencase;
679 case scm_tc7_ivect:
680 case scm_tc7_uvect:
681 IVDEP (src != dst,
682 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
683 {
684 d[i_d][0] = ((long *) s)[i_s];
685 d[i_d][1] = 0.0;
686 }
687 )
688 break;
689 case scm_tc7_fvect:
690 IVDEP (src != dst,
691 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
692 {
693 d[i_d][0] = ((float *) s)[i_s];
694 d[i_d][1] = 0.0;
695 }
696 )
697 break;
698 case scm_tc7_dvect:
699 IVDEP (src != dst,
700 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
701 {
702 d[i_d][0] = ((double *) s)[i_s];
703 d[i_d][1] = 0.0;
704 }
705 )
706 break;
707 case scm_tc7_cvect:
708 IVDEP (src != dst,
709 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
710 {
711 d[i_d][0] = s[i_s][0];
712 d[i_d][1] = s[i_s][1];
713 }
714 )
715 }
716 break;
717 }
718 }
719#endif /* SCM_FLOATS */
720 return 1;
721}
722
723
724SCM_PROC(s_serial_array_copy_x, "serial-array-copy!", 2, 0, 0, scm_array_copy_x);
725SCM_PROC(s_array_copy_x, "array-copy!", 2, 0, 0, scm_array_copy_x);
726#ifdef __STDC__
727SCM
728scm_array_copy_x (SCM src, SCM dst)
729#else
730SCM
731scm_array_copy_x (src, dst)
732 SCM src;
733 SCM dst;
734#endif
735{
736 scm_ramapc (racp, SCM_UNDEFINED, src, scm_cons (dst, SCM_EOL), s_array_copy_x);
737 return SCM_UNSPECIFIED;
738}
739
740/* Functions callable by ARRAY-MAP! */
741
742#ifdef __STDC__
743int
744scm_ra_eqp (SCM ra0, SCM ras)
745#else
746int
747scm_ra_eqp (ra0, ras)
748 SCM ra0;
749 SCM ras;
750#endif
751{
752 SCM ra1 = SCM_CAR (ras), ra2 = SCM_CAR (SCM_CDR (ras));
753 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
754 scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
755 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
756 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
757 long inc2 = SCM_ARRAY_DIMS (ra1)->inc;
758 ra0 = SCM_ARRAY_V (ra0);
759 ra1 = SCM_ARRAY_V (ra1);
760 ra2 = SCM_ARRAY_V (ra2);
761 switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
762 {
763 default:
764 {
765 SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
766 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
767 if BVE_REF
768 (ra0, i0)
769 if SCM_FALSEP
770 (scm_eq_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2)))
771 BVE_CLR (ra0, i0);
772 break;
773 }
774 case scm_tc7_uvect:
775 case scm_tc7_ivect:
776 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
777 if BVE_REF
778 (ra0, i0)
779 if (SCM_VELTS (ra1)[i1] != SCM_VELTS (ra2)[i2])
780 BVE_CLR (ra0, i0);
781 break;
782#ifdef SCM_FLOATS
783#ifdef SCM_SINGLES
784 case scm_tc7_fvect:
785 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
786 if BVE_REF
787 (ra0, i0)
788 if (((float *) SCM_VELTS (ra1))[i1] != ((float *) SCM_VELTS (ra2))[i2])
789 BVE_CLR (ra0, i0);
790 break;
791#endif /*SCM_SINGLES*/
792 case scm_tc7_dvect:
793 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
794 if BVE_REF
795 (ra0, i0)
796 if (((double *) SCM_VELTS (ra1))[i1] != ((double *) SCM_VELTS (ra2))[i2])
797 BVE_CLR (ra0, i0);
798 break;
799 case scm_tc7_cvect:
800 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
801 if BVE_REF
802 (ra0, i0)
803 if (((double *) SCM_VELTS (ra1))[2 * i1] != ((double *) SCM_VELTS (ra2))[2 * i2] ||
804 ((double *) SCM_VELTS (ra1))[2 * i1 + 1] != ((double *) SCM_VELTS (ra2))[2 * i2 + 1])
805 BVE_CLR (ra0, i0);
806 break;
807#endif /*SCM_FLOATS*/
808 }
809 return 1;
810}
811
812/* opt 0 means <, nonzero means >= */
813#ifdef __STDC__
814static int
815ra_compare (SCM ra0, SCM ra1, SCM ra2, int opt)
816#else
817static int
818ra_compare (ra0, ra1, ra2, opt)
819 SCM ra0;
820 SCM ra1;
821 SCM ra2;
822 int opt;
823#endif
824{
825 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
826 scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
827 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
828 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
829 long inc2 = SCM_ARRAY_DIMS (ra1)->inc;
830 ra0 = SCM_ARRAY_V (ra0);
831 ra1 = SCM_ARRAY_V (ra1);
832 ra2 = SCM_ARRAY_V (ra2);
833 switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
834 {
835 default:
836 {
837 SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
838 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
839 if BVE_REF
840 (ra0, i0)
841 if (opt ?
842 SCM_NFALSEP (scm_less_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))) :
843 SCM_FALSEP (scm_less_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))))
844 BVE_CLR (ra0, i0);
845 break;
846 }
847 case scm_tc7_uvect:
848 case scm_tc7_ivect:
849 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
850 {
851 if BVE_REF
852 (ra0, i0)
853 if (opt ?
854 SCM_VELTS (ra1)[i1] < SCM_VELTS (ra2)[i2] :
855 SCM_VELTS (ra1)[i1] >= SCM_VELTS (ra2)[i2])
856 BVE_CLR (ra0, i0);
857 }
858 break;
859#ifdef SCM_FLOATS
860#ifdef SCM_SINGLES
861 case scm_tc7_fvect:
862 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
863 if BVE_REF
864 (ra0, i0)
865 if (opt ?
866 ((float *) SCM_VELTS (ra1))[i1] < ((float *) SCM_VELTS (ra2))[i2] :
867 ((float *) SCM_VELTS (ra1))[i1] >= ((float *) SCM_VELTS (ra2))[i2])
868 BVE_CLR (ra0, i0);
869 break;
870#endif /*SCM_SINGLES*/
871 case scm_tc7_dvect:
872 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
873 if BVE_REF
874 (ra0, i0)
875 if (opt ?
876 ((double *) SCM_VELTS (ra1))[i1] < ((double *) SCM_VELTS (ra2))[i2] :
877 ((double *) SCM_VELTS (ra1))[i1] >= ((double *) SCM_VELTS (ra2))[i2])
878 BVE_CLR (ra0, i0);
879 break;
880#endif /*SCM_FLOATS*/
881 }
882 return 1;
883}
884
885
886#ifdef __STDC__
887int
888scm_ra_lessp (SCM ra0, SCM ras)
889#else
890int
891scm_ra_lessp (ra0, ras)
892 SCM ra0;
893 SCM ras;
894#endif
895{
896 return ra_compare (ra0, SCM_CAR (ras), SCM_CAR (SCM_CDR (ras)), 0);
897}
898
899#ifdef __STDC__
900int
901scm_ra_leqp (SCM ra0, SCM ras)
902#else
903int
904scm_ra_leqp (ra0, ras)
905 SCM ra0;
906 SCM ras;
907#endif
908{
909 return ra_compare (ra0, SCM_CAR (SCM_CDR (ras)), SCM_CAR (ras), 1);
910}
911
912#ifdef __STDC__
913int
914scm_ra_grp (SCM ra0, SCM ras)
915#else
916int
917scm_ra_grp (ra0, ras)
918 SCM ra0;
919 SCM ras;
920#endif
921{
922 return ra_compare (ra0, SCM_CAR (SCM_CDR (ras)), SCM_CAR (ras), 0);
923}
924
925#ifdef __STDC__
926int
927scm_ra_greqp (SCM ra0, SCM ras)
928#else
929int
930scm_ra_greqp (ra0, ras)
931 SCM ra0;
932 SCM ras;
933#endif
934{
935 return ra_compare (ra0, SCM_CAR (ras), SCM_CAR (SCM_CDR (ras)), 1);
936}
937
938
939#ifdef __STDC__
940int
941scm_ra_sum (SCM ra0, SCM ras)
942#else
943int
944scm_ra_sum (ra0, ras)
945 SCM ra0;
946 SCM ras;
947#endif
948{
949 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
950 scm_sizet i0 = SCM_ARRAY_BASE (ra0);
951 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
952 ra0 = SCM_ARRAY_V (ra0);
953 if SCM_NNULLP
954 (ras)
955 {
956 SCM ra1 = SCM_CAR (ras);
957 scm_sizet i1 = SCM_ARRAY_BASE (ra1);
958 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
959 ra1 = SCM_ARRAY_V (ra1);
960 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
961 {
962 default:
963 {
964 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
965 for (; n-- > 0; i0 += inc0, i1 += inc1)
966 scm_array_set_x (ra0, scm_sum (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
967 SCM_MAKINUM (i0));
968 break;
969 }
970 case scm_tc7_uvect:
971 case scm_tc7_ivect:
972 {
973 long *v0 = SCM_VELTS (ra0);
974 long *v1 = SCM_VELTS (ra1);
975 IVDEP (ra0 != ra1,
976 for (; n-- > 0; i0 += inc0, i1 += inc1)
977 v0[i0] += v1[i1]);
978 break;
979 }
980#ifdef SCM_FLOATS
981#ifdef SCM_SINGLES
982 case scm_tc7_fvect:
983 {
984 float *v0 = (float *) SCM_VELTS (ra0);
985 float *v1 = (float *) SCM_VELTS (ra1);
986 IVDEP (ra0 != ra1,
987 for (; n-- > 0; i0 += inc0, i1 += inc1)
988 v0[i0] += v1[i1]);
989 break;
990 }
991#endif /* SCM_SINGLES */
992 case scm_tc7_dvect:
993 {
994 double *v0 = (double *) SCM_VELTS (ra0);
995 double *v1 = (double *) SCM_VELTS (ra1);
996 IVDEP (ra0 != ra1,
997 for (; n-- > 0; i0 += inc0, i1 += inc1)
998 v0[i0] += v1[i1]);
999 break;
1000 }
1001 case scm_tc7_cvect:
1002 {
1003 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
1004 double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1);
1005 IVDEP (ra0 != ra1,
1006 for (; n-- > 0; i0 += inc0, i1 += inc1)
1007 {
1008 v0[i0][0] += v1[i1][0];
1009 v0[i0][1] += v1[i1][1];
1010 }
1011 );
1012 break;
1013 }
1014#endif /* SCM_FLOATS */
1015 }
1016 }
1017 return 1;
1018}
1019
1020
1021#ifdef __STDC__
1022int
1023scm_ra_difference (SCM ra0, SCM ras)
1024#else
1025int
1026scm_ra_difference (ra0, ras)
1027 SCM ra0;
1028 SCM ras;
1029#endif
1030{
1031 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1032 scm_sizet i0 = SCM_ARRAY_BASE (ra0);
1033 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1034 ra0 = SCM_ARRAY_V (ra0);
1035 if SCM_NULLP
1036 (ras)
1037 {
1038 switch SCM_TYP7
1039 (ra0)
1040 {
1041 default:
1042 {
1043 SCM e0 = SCM_UNDEFINED;
1044 for (; n-- > 0; i0 += inc0)
1045 scm_array_set_x (ra0, scm_difference (RVREF (ra0, i0, e0), SCM_UNDEFINED), SCM_MAKINUM (i0));
1046 break;
1047 }
1048#ifdef SCM_FLOATS
1049#ifdef SCM_SINGLES
1050 case scm_tc7_fvect:
1051 {
1052 float *v0 = (float *) SCM_VELTS (ra0);
1053 for (; n-- > 0; i0 += inc0)
1054 v0[i0] = -v0[i0];
1055 break;
1056 }
1057#endif /* SCM_SINGLES */
1058 case scm_tc7_dvect:
1059 {
1060 double *v0 = (double *) SCM_VELTS (ra0);
1061 for (; n-- > 0; i0 += inc0)
1062 v0[i0] = -v0[i0];
1063 break;
1064 }
1065 case scm_tc7_cvect:
1066 {
1067 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
1068 for (; n-- > 0; i0 += inc0)
1069 {
1070 v0[i0][0] = -v0[i0][0];
1071 v0[i0][1] = -v0[i0][1];
1072 }
1073 break;
1074 }
1075#endif /* SCM_FLOATS */
1076 }
1077 }
1078 else
1079 {
1080 SCM ra1 = SCM_CAR (ras);
1081 scm_sizet i1 = SCM_ARRAY_BASE (ra1);
1082 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1083 ra1 = SCM_ARRAY_V (ra1);
1084 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
1085 {
1086 default:
1087 {
1088 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1089 for (; n-- > 0; i0 += inc0, i1 += inc1)
1090 scm_array_set_x (ra0, scm_difference (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)), SCM_MAKINUM (i0));
1091 break;
1092 }
1093#ifdef SCM_FLOATS
1094#ifdef SCM_SINGLES
1095 case scm_tc7_fvect:
1096 {
1097 float *v0 = (float *) SCM_VELTS (ra0);
1098 float *v1 = (float *) SCM_VELTS (ra1);
1099 IVDEP (ra0 != ra1,
1100 for (; n-- > 0; i0 += inc0, i1 += inc1)
1101 v0[i0] -= v1[i1]);
1102 break;
1103 }
1104#endif /* SCM_SINGLES */
1105 case scm_tc7_dvect:
1106 {
1107 double *v0 = (double *) SCM_VELTS (ra0);
1108 double *v1 = (double *) SCM_VELTS (ra1);
1109 IVDEP (ra0 != ra1,
1110 for (; n-- > 0; i0 += inc0, i1 += inc1)
1111 v0[i0] -= v1[i1]);
1112 break;
1113 }
1114 case scm_tc7_cvect:
1115 {
1116 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
1117 double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1);
1118 IVDEP (ra0 != ra1,
1119 for (; n-- > 0; i0 += inc0, i1 += inc1)
1120 {
1121 v0[i0][0] -= v1[i1][0];
1122 v0[i0][1] -= v1[i1][1];
1123 }
1124 )
1125 break;
1126 }
1127#endif /* SCM_FLOATS */
1128 }
1129 }
1130 return 1;
1131}
1132
1133
1134#ifdef __STDC__
1135int
1136scm_ra_product (SCM ra0, SCM ras)
1137#else
1138int
1139scm_ra_product (ra0, ras)
1140 SCM ra0;
1141 SCM ras;
1142#endif
1143{
1144 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1145 scm_sizet i0 = SCM_ARRAY_BASE (ra0);
1146 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1147 ra0 = SCM_ARRAY_V (ra0);
1148 if SCM_NNULLP
1149 (ras)
1150 {
1151 SCM ra1 = SCM_CAR (ras);
1152 scm_sizet i1 = SCM_ARRAY_BASE (ra1);
1153 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1154 ra1 = SCM_ARRAY_V (ra1);
1155 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
1156 {
1157 default:
1158 {
1159 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1160 for (; n-- > 0; i0 += inc0, i1 += inc1)
1161 scm_array_set_x (ra0, scm_product (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
1162 SCM_MAKINUM (i0));
1163 break;
1164 }
1165 case scm_tc7_uvect:
1166 case scm_tc7_ivect:
1167 {
1168 long *v0 = SCM_VELTS (ra0);
1169 long *v1 = SCM_VELTS (ra1);
1170 IVDEP (ra0 != ra1,
1171 for (; n-- > 0; i0 += inc0, i1 += inc1)
1172 v0[i0] *= v1[i1]);
1173 break;
1174 }
1175#ifdef SCM_FLOATS
1176#ifdef SCM_SINGLES
1177 case scm_tc7_fvect:
1178 {
1179 float *v0 = (float *) SCM_VELTS (ra0);
1180 float *v1 = (float *) SCM_VELTS (ra1);
1181 IVDEP (ra0 != ra1,
1182 for (; n-- > 0; i0 += inc0, i1 += inc1)
1183 v0[i0] *= v1[i1]);
1184 break;
1185 }
1186#endif /* SCM_SINGLES */
1187 case scm_tc7_dvect:
1188 {
1189 double *v0 = (double *) SCM_VELTS (ra0);
1190 double *v1 = (double *) SCM_VELTS (ra1);
1191 IVDEP (ra0 != ra1,
1192 for (; n-- > 0; i0 += inc0, i1 += inc1)
1193 v0[i0] *= v1[i1]);
1194 break;
1195 }
1196 case scm_tc7_cvect:
1197 {
1198 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
1199 register double r;
1200 double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1);
1201 IVDEP (ra0 != ra1,
1202 for (; n-- > 0; i0 += inc0, i1 += inc1)
1203 {
1204 r = v0[i0][0] * v1[i1][0] - v0[i0][1] * v1[i1][1];
1205 v0[i0][1] = v0[i0][0] * v1[i1][1] + v0[i0][1] * v1[i1][0];
1206 v0[i0][0] = r;
1207 }
1208 );
1209 break;
1210 }
1211#endif /* SCM_FLOATS */
1212 }
1213 }
1214 return 1;
1215}
1216
1217#ifdef __STDC__
1218int
1219scm_ra_divide (SCM ra0, SCM ras)
1220#else
1221int
1222scm_ra_divide (ra0, ras)
1223 SCM ra0;
1224 SCM ras;
1225#endif
1226{
1227 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1228 scm_sizet i0 = SCM_ARRAY_BASE (ra0);
1229 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1230 ra0 = SCM_ARRAY_V (ra0);
1231 if SCM_NULLP
1232 (ras)
1233 {
1234 switch SCM_TYP7
1235 (ra0)
1236 {
1237 default:
1238 {
1239 SCM e0 = SCM_UNDEFINED;
1240 for (; n-- > 0; i0 += inc0)
1241 scm_array_set_x (ra0, scm_divide (RVREF (ra0, i0, e0), SCM_UNDEFINED), SCM_MAKINUM (i0));
1242 break;
1243 }
1244#ifdef SCM_FLOATS
1245#ifdef SCM_SINGLES
1246 case scm_tc7_fvect:
1247 {
1248 float *v0 = (float *) SCM_VELTS (ra0);
1249 for (; n-- > 0; i0 += inc0)
1250 v0[i0] = 1.0 / v0[i0];
1251 break;
1252 }
1253#endif /* SCM_SINGLES */
1254 case scm_tc7_dvect:
1255 {
1256 double *v0 = (double *) SCM_VELTS (ra0);
1257 for (; n-- > 0; i0 += inc0)
1258 v0[i0] = 1.0 / v0[i0];
1259 break;
1260 }
1261 case scm_tc7_cvect:
1262 {
1263 register double d;
1264 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
1265 for (; n-- > 0; i0 += inc0)
1266 {
1267 d = v0[i0][0] * v0[i0][0] + v0[i0][1] * v0[i0][1];
1268 v0[i0][0] /= d;
1269 v0[i0][1] /= -d;
1270 }
1271 break;
1272 }
1273#endif /* SCM_FLOATS */
1274 }
1275 }
1276 else
1277 {
1278 SCM ra1 = SCM_CAR (ras);
1279 scm_sizet i1 = SCM_ARRAY_BASE (ra1);
1280 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1281 ra1 = SCM_ARRAY_V (ra1);
1282 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
1283 {
1284 default:
1285 {
1286 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1287 for (; n-- > 0; i0 += inc0, i1 += inc1)
1288 scm_array_set_x (ra0, scm_divide (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)), SCM_MAKINUM (i0));
1289 break;
1290 }
1291#ifdef SCM_FLOATS
1292#ifdef SCM_SINGLES
1293 case scm_tc7_fvect:
1294 {
1295 float *v0 = (float *) SCM_VELTS (ra0);
1296 float *v1 = (float *) SCM_VELTS (ra1);
1297 IVDEP (ra0 != ra1,
1298 for (; n-- > 0; i0 += inc0, i1 += inc1)
1299 v0[i0] /= v1[i1]);
1300 break;
1301 }
1302#endif /* SCM_SINGLES */
1303 case scm_tc7_dvect:
1304 {
1305 double *v0 = (double *) SCM_VELTS (ra0);
1306 double *v1 = (double *) SCM_VELTS (ra1);
1307 IVDEP (ra0 != ra1,
1308 for (; n-- > 0; i0 += inc0, i1 += inc1)
1309 v0[i0] /= v1[i1]);
1310 break;
1311 }
1312 case scm_tc7_cvect:
1313 {
1314 register double d, r;
1315 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
1316 double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1);
1317 IVDEP (ra0 != ra1,
1318 for (; n-- > 0; i0 += inc0, i1 += inc1)
1319 {
1320 d = v1[i1][0] * v1[i1][0] + v1[i1][1] * v1[i1][1];
1321 r = (v0[i0][0] * v1[i1][0] + v0[i0][1] * v1[i1][1]) / d;
1322 v0[i0][1] = (v0[i0][1] * v1[i1][0] - v0[i0][0] * v1[i1][1]) / d;
1323 v0[i0][0] = r;
1324 }
1325 )
1326 break;
1327 }
1328#endif /* SCM_FLOATS */
1329 }
1330 }
1331 return 1;
1332}
1333
1334#ifdef __STDC__
1335int
1336scm_array_identity (SCM src, SCM dst)
1337#else
1338int
1339scm_array_identity (dst, src)
1340 SCM src;
1341 SCM dst;
1342#endif
1343{
1344 return racp (SCM_CAR (src), scm_cons (dst, SCM_EOL));
1345}
1346
1347
1348#ifdef __STDC__
1349static
1350int
1351ramap (SCM ra0, SCM proc, SCM ras)
1352#else
1353static int
1354ramap (ra0, proc, ras)
1355 SCM ra0;
1356 SCM proc;
1357 SCM ras;
1358#endif
1359{
1360 long i = SCM_ARRAY_DIMS (ra0)->lbnd;
1361 long inc = SCM_ARRAY_DIMS (ra0)->inc;
1362 long n = SCM_ARRAY_DIMS (ra0)->ubnd;
1363 long base = SCM_ARRAY_BASE (ra0) - i * inc;
1364 ra0 = SCM_ARRAY_V (ra0);
1365 if SCM_NULLP
1366 (ras)
1367 for (; i <= n; i++)
1368 scm_array_set_x (ra0, scm_apply (proc, SCM_EOL, SCM_EOL), SCM_MAKINUM (i * inc + base));
1369 else
1370 {
1371 SCM ra1 = SCM_CAR (ras);
1372 SCM args, *ve = &ras;
1373 scm_sizet k, i1 = SCM_ARRAY_BASE (ra1);
1374 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1375 ra1 = SCM_ARRAY_V (ra1);
1376 ras = SCM_CDR (ras);
1377 if SCM_NULLP
1378 (ras)
1379 ras = scm_nullvect;
1380 else
1381 {
1382 ras = scm_vector (ras);
1383 ve = SCM_VELTS (ras);
1384 }
1385 for (; i <= n; i++, i1 += inc1)
1386 {
1387 args = SCM_EOL;
1388 for (k = SCM_LENGTH (ras); k--;)
1389 args = scm_cons (scm_uniform_vector_ref (ve[k], SCM_MAKINUM (i)), args);
1390 args = scm_cons (scm_cvref (ra1, i1, SCM_UNDEFINED), args);
1391 scm_array_set_x (ra0, scm_apply (proc, args, SCM_EOL), SCM_MAKINUM (i * inc + base));
1392 }
1393 }
1394 return 1;
1395}
1396
1397#ifdef __STDC__
1398static int
1399ramap_cxr (SCM ra0, SCM proc, SCM ras)
1400#else
1401static int
1402ramap_cxr (ra0, proc, ras)
1403 SCM ra0;
1404 SCM proc;
1405 SCM ras;
1406#endif
1407{
1408 SCM ra1 = SCM_CAR (ras);
1409 SCM e1 = SCM_UNDEFINED;
1410 scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
1411 long inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1412 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra1)->lbnd + 1;
1413 ra0 = SCM_ARRAY_V (ra0);
1414 ra1 = SCM_ARRAY_V (ra1);
1415 switch SCM_TYP7
1416 (ra0)
1417 {
1418 default:
1419 gencase:
1420 for (; n-- > 0; i0 += inc0, i1 += inc1)
1421 scm_array_set_x (ra0, scm_apply (proc, RVREF (ra1, i1, e1), scm_listofnull), SCM_MAKINUM (i0));
1422 break;
1423#ifdef SCM_FLOATS
1424#ifdef SCM_SINGLES
1425 case scm_tc7_fvect:
1426 {
1427 float *dst = (float *) SCM_VELTS (ra0);
1428 switch SCM_TYP7
1429 (ra1)
1430 {
1431 default:
1432 goto gencase;
1433 case scm_tc7_fvect:
1434 for (; n-- > 0; i0 += inc0, i1 += inc1)
1435 dst[i0] = SCM_DSUBRF (proc) ((double) ((float *) SCM_VELTS (ra1))[i1]);
1436 break;
1437 case scm_tc7_uvect:
1438 case scm_tc7_ivect:
1439 for (; n-- > 0; i0 += inc0, i1 += inc1)
1440 dst[i0] = SCM_DSUBRF (proc) ((double) SCM_VELTS (ra1)[i1]);
1441 break;
1442 }
1443 break;
1444 }
1445#endif /* SCM_SINGLES */
1446 case scm_tc7_dvect:
1447 {
1448 double *dst = (double *) SCM_VELTS (ra0);
1449 switch SCM_TYP7
1450 (ra1)
1451 {
1452 default:
1453 goto gencase;
1454 case scm_tc7_dvect:
1455 for (; n-- > 0; i0 += inc0, i1 += inc1)
1456 dst[i0] = SCM_DSUBRF (proc) (((double *) SCM_VELTS (ra1))[i1]);
1457 break;
1458 case scm_tc7_uvect:
1459 case scm_tc7_ivect:
1460 for (; n-- > 0; i0 += inc0, i1 += inc1)
1461 dst[i0] = SCM_DSUBRF (proc) ((double) SCM_VELTS (ra1)[i1]);
1462 break;
1463 }
1464 break;
1465 }
1466#endif /* SCM_FLOATS */
1467 }
1468 return 1;
1469}
1470
1471
1472#ifdef __STDC__
1473static int
1474ramap_rp (SCM ra0, SCM proc, SCM ras)
1475#else
1476static int
1477ramap_rp (ra0, proc, ras)
1478 SCM ra0;
1479 SCM proc;
1480 SCM ras;
1481#endif
1482{
1483 SCM ra1 = SCM_CAR (ras), ra2 = SCM_CAR (SCM_CDR (ras));
1484 SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
1485 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1486 scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
1487 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1488 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1489 long inc2 = SCM_ARRAY_DIMS (ra1)->inc;
1490 ra0 = SCM_ARRAY_V (ra0);
1491 ra1 = SCM_ARRAY_V (ra1);
1492 ra2 = SCM_ARRAY_V (ra2);
1493 switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
1494 {
1495 default:
1496 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
1497 if BVE_REF
1498 (ra0, i0)
1499 if SCM_FALSEP
1500 (SCM_SUBRF (proc) (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2)))
1501 BVE_CLR (ra0, i0);
1502 break;
1503 case scm_tc7_uvect:
1504 case scm_tc7_ivect:
1505 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
1506 if BVE_REF
1507 (ra0, i0)
1508 {
1509 if SCM_FALSEP
1510 (SCM_SUBRF (proc) (SCM_MAKINUM (SCM_VELTS (ra1)[i1]),
1511 SCM_MAKINUM (SCM_VELTS (ra2)[i2])))
1512 BVE_CLR (ra0, i0);
1513 }
1514 break;
1515#ifdef SCM_FLOATS
1516#ifdef SCM_SINGLES
1517 case scm_tc7_fvect:
1518 {
1519 SCM a1 = scm_makflo (1.0), a2 = scm_makflo (1.0);
1520 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
1521 if BVE_REF
1522 (ra0, i0)
1523 {
1524 SCM_FLO (a1) = ((float *) SCM_VELTS (ra1))[i1];
1525 SCM_FLO (a2) = ((float *) SCM_VELTS (ra2))[i2];
1526 if SCM_FALSEP
1527 (SCM_SUBRF (proc) (a1, a2))
1528 BVE_CLR (ra0, i0);
1529 }
1530 break;
1531 }
1532#endif /*SCM_SINGLES*/
1533 case scm_tc7_dvect:
1534 {
1535 SCM a1 = scm_makdbl (1.0 / 3.0, 0.0), a2 = scm_makdbl (1.0 / 3.0, 0.0);
1536 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
1537 if BVE_REF
1538 (ra0, i0)
1539 {
1540 SCM_REAL (a1) = ((double *) SCM_VELTS (ra1))[i1];
1541 SCM_REAL (a2) = ((double *) SCM_VELTS (ra2))[i2];
1542 if SCM_FALSEP
1543 (SCM_SUBRF (proc) (a1, a2))
1544 BVE_CLR (ra0, i0);
1545 }
1546 break;
1547 }
1548 case scm_tc7_cvect:
1549 {
1550 SCM a1 = scm_makdbl (1.0, 1.0), a2 = scm_makdbl (1.0, 1.0);
1551 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
1552 if BVE_REF
1553 (ra0, i0)
1554 {
1555 SCM_REAL (a1) = ((double *) SCM_VELTS (ra1))[2 * i1];
1556 SCM_IMAG (a1) = ((double *) SCM_VELTS (ra1))[2 * i1 + 1];
1557 SCM_REAL (a2) = ((double *) SCM_VELTS (ra2))[2 * i2];
1558 SCM_IMAG (a2) = ((double *) SCM_VELTS (ra2))[2 * i2 + 1];
1559 if SCM_FALSEP
1560 (SCM_SUBRF (proc) (a1, a2))
1561 BVE_CLR (ra0, i0);
1562 }
1563 break;
1564 }
1565#endif /*SCM_FLOATS*/
1566 }
1567 return 1;
1568}
1569
1570
1571#ifdef __STDC__
1572static int
1573ramap_1 (SCM ra0, SCM proc, SCM ras)
1574#else
1575static int
1576ramap_1 (ra0, proc, ras)
1577 SCM ra0;
1578 SCM proc;
1579 SCM ras;
1580#endif
1581{
1582 SCM ra1 = SCM_CAR (ras);
1583 SCM e1 = SCM_UNDEFINED;
1584 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1585 scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
1586 long inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1587 ra0 = SCM_ARRAY_V (ra0);
1588 ra1 = SCM_ARRAY_V (ra1);
1589 if (scm_tc7_vector == SCM_TYP7 (ra0))
1590 for (; n-- > 0; i0 += inc0, i1 += inc1)
1591 scm_array_set_x (ra0, SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED)), SCM_MAKINUM (i0));
1592 else
1593 for (; n-- > 0; i0 += inc0, i1 += inc1)
1594 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra1, i1, e1)), SCM_MAKINUM (i0));
1595 return 1;
1596}
1597
1598
1599#ifdef __STDC__
1600static int
1601ramap_2o (SCM ra0, SCM proc, SCM ras)
1602#else
1603static int
1604ramap_2o (ra0, proc, ras)
1605 SCM ra0;
1606 SCM proc;
1607 SCM ras;
1608#endif
1609{
1610 SCM ra1 = SCM_CAR (ras);
1611 SCM e1 = SCM_UNDEFINED;
1612 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1613 scm_sizet i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
1614 long inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1615 ra0 = SCM_ARRAY_V (ra0);
1616 ra1 = SCM_ARRAY_V (ra1);
1617 ras = SCM_CDR (ras);
1618 if SCM_NULLP
1619 (ras)
1620 {
1621 if (scm_tc7_vector == SCM_TYP7 (ra0))
1622 for (; n-- > 0; i0 += inc0, i1 += inc1)
1623 scm_array_set_x (ra0, SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED), SCM_UNDEFINED),
1624 SCM_MAKINUM (i0));
1625 else
1626 for (; n-- > 0; i0 += inc0, i1 += inc1)
1627 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra1, i1, e1), SCM_UNDEFINED),
1628 SCM_MAKINUM (i0));
1629 }
1630 else
1631 {
1632 SCM ra2 = SCM_CAR (ras);
1633 SCM e2 = SCM_UNDEFINED;
1634 scm_sizet i2 = SCM_ARRAY_BASE (ra2);
1635 long inc2 = SCM_ARRAY_DIMS (ra2)->inc;
1636 ra2 = SCM_ARRAY_V (ra2);
1637 if (scm_tc7_vector == SCM_TYP7 (ra0))
1638 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
1639 scm_array_set_x (ra0,
1640 SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED), scm_cvref (ra2, i2, SCM_UNDEFINED)),
1641 SCM_MAKINUM (i0));
1642 else
1643 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
1644 scm_array_set_x (ra0,
1645 SCM_SUBRF (proc) (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2)),
1646 SCM_MAKINUM (i0));
1647 }
1648 return 1;
1649}
1650
1651
1652#ifdef __STDC__
1653static int
1654ramap_a (SCM ra0, SCM proc, SCM ras)
1655#else
1656static int
1657ramap_a (ra0, proc, ras)
1658 SCM ra0;
1659 SCM proc;
1660 SCM ras;
1661#endif
1662{
1663 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1664 long n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1665 scm_sizet i0 = SCM_ARRAY_BASE (ra0);
1666 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1667 ra0 = SCM_ARRAY_V (ra0);
1668 if SCM_NULLP
1669 (ras)
1670 for (; n-- > 0; i0 += inc0)
1671 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra0, i0, e0), SCM_UNDEFINED), SCM_MAKINUM (i0));
1672 else
1673 {
1674 SCM ra1 = SCM_CAR (ras);
1675 scm_sizet i1 = SCM_ARRAY_BASE (ra1);
1676 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1677 ra1 = SCM_ARRAY_V (ra1);
1678 for (; n-- > 0; i0 += inc0, i1 += inc1)
1679 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
1680 SCM_MAKINUM (i0));
1681 }
1682 return 1;
1683}
1684
1685SCM_PROC(s_serial_array_map, "serial-array-map", 2, 0, 1, scm_array_map);
1686SCM_PROC(s_array_map, "array-map", 2, 0, 1, scm_array_map);
1687#ifdef __STDC__
1688SCM
1689scm_array_map (SCM ra0, SCM proc, SCM lra)
1690#else
1691SCM
1692scm_array_map (ra0, proc, lra)
1693 SCM ra0;
1694 SCM proc;
1695 SCM lra;
1696#endif
1697{
1698 SCM_ASSERT (SCM_BOOL_T == scm_procedure_p (proc), proc, SCM_ARG2, s_array_map);
1699 switch (SCM_TYP7 (proc))
1700 {
1701 default:
1702 gencase:
1703 scm_ramapc (ramap, proc, ra0, lra, s_array_map);
1704 return SCM_UNSPECIFIED;
1705 case scm_tc7_subr_1:
1706 scm_ramapc (ramap_1, proc, ra0, lra, s_array_map);
1707 return SCM_UNSPECIFIED;
1708 case scm_tc7_subr_2:
1709 case scm_tc7_subr_2o:
1710 scm_ramapc (ramap_2o, proc, ra0, lra, s_array_map);
1711 return SCM_UNSPECIFIED;
1712 case scm_tc7_cxr:
1713 if (!SCM_SUBRF (proc))
1714 goto gencase;
1715 scm_ramapc (ramap_cxr, proc, ra0, lra, s_array_map);
1716 return SCM_UNSPECIFIED;
1717 case scm_tc7_rpsubr:
1718 {
1719 ra_iproc *p;
1720 if (SCM_FALSEP (scm_array_p (ra0, SCM_BOOL_T)))
1721 goto gencase;
1722 scm_array_fill_x (ra0, SCM_BOOL_T);
1723 for (p = ra_rpsubrs; p->name; p++)
1724 if (proc == p->sproc)
1725 {
1726 while (SCM_NNULLP (lra) && SCM_NNULLP (SCM_CDR (lra)))
1727 {
1728 scm_ramapc (p->vproc, SCM_UNDEFINED, ra0, lra, s_array_map);
1729 lra = SCM_CDR (lra);
1730 }
1731 return SCM_UNSPECIFIED;
1732 }
1733 while (SCM_NNULLP (lra) && SCM_NNULLP (SCM_CDR (lra)))
1734 {
1735 scm_ramapc (ramap_rp, proc, ra0, lra, s_array_map);
1736 lra = SCM_CDR (lra);
1737 }
1738 return SCM_UNSPECIFIED;
1739 }
1740 case scm_tc7_asubr:
1741 if SCM_NULLP
1742 (lra)
1743 {
1744 SCM prot, fill = SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED);
1745 if SCM_INUMP
1746 (fill)
1747 {
1748 prot = scm_array_prototype (ra0);
1749 if (SCM_NIMP (prot) && SCM_INEXP (prot))
1750 fill = scm_makdbl ((double) SCM_INUM (fill), 0.0);
1751 }
1752
1753 scm_array_fill_x (ra0, fill);
1754 }
1755 else
1756 {
1757 SCM tail, ra1 = SCM_CAR (lra);
1758 SCM v0 = (SCM_NIMP (ra0) && SCM_ARRAYP (ra0) ? SCM_ARRAY_V (ra0) : ra0);
1759 ra_iproc *p;
1760 /* Check to see if order might matter.
1761 This might be an argument for a separate
1762 SERIAL-ARRAY-MAP! */
1763 if (v0 == ra1 || (SCM_NIMP (ra1) && SCM_ARRAYP (ra1) && v0 == SCM_ARRAY_V (ra1)))
1764 if (ra0 != ra1 || (SCM_ARRAYP(ra0) && !SCM_ARRAY_CONTP(ra0)))
1765 goto gencase;
1766 for (tail = SCM_CDR (lra); SCM_NNULLP (tail); tail = SCM_CDR (tail))
1767 {
1768 ra1 = SCM_CAR (tail);
1769 if (v0 == ra1 || (SCM_NIMP (ra1) && SCM_ARRAYP (ra1) && v0 == SCM_ARRAY_V (ra1)))
1770 goto gencase;
1771 }
1772 for (p = ra_asubrs; p->name; p++)
1773 if (proc == p->sproc)
1774 {
1775 if (ra0 != SCM_CAR (lra))
1776 scm_ramapc (scm_array_identity, SCM_UNDEFINED, ra0, scm_cons (SCM_CAR (lra), SCM_EOL), s_array_map);
1777 lra = SCM_CDR (lra);
1778 while (1)
1779 {
1780 scm_ramapc (p->vproc, SCM_UNDEFINED, ra0, lra, s_array_map);
1781 if (SCM_IMP (lra) || SCM_IMP (SCM_CDR (lra)))
1782 return SCM_UNSPECIFIED;
1783 lra = SCM_CDR (lra);
1784 }
1785 }
1786 scm_ramapc (ramap_2o, proc, ra0, lra, s_array_map);
1787 lra = SCM_CDR (lra);
1788 if SCM_NIMP
1789 (lra)
1790 for (lra = SCM_CDR (lra); SCM_NIMP (lra); lra = SCM_CDR (lra))
1791 scm_ramapc (ramap_a, proc, ra0, lra, s_array_map);
1792 }
1793 return SCM_UNSPECIFIED;
1794 }
1795}
1796
1797#ifdef __STDC__
1798static int
1799rafe (SCM ra0, SCM proc, SCM ras)
1800#else
1801static int
1802rafe (ra0, proc, ras)
1803 SCM ra0;
1804 SCM proc;
1805 SCM ras;
1806#endif
1807{
1808 long i = SCM_ARRAY_DIMS (ra0)->lbnd;
1809 scm_sizet i0 = SCM_ARRAY_BASE (ra0);
1810 long inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1811 long n = SCM_ARRAY_DIMS (ra0)->ubnd;
1812 ra0 = SCM_ARRAY_V (ra0);
1813 if SCM_NULLP
1814 (ras)
1815 for (; i <= n; i++, i0 += inc0)
1816 scm_apply (proc, scm_cvref (ra0, i0, SCM_UNDEFINED), scm_listofnull);
1817 else
1818 {
1819 SCM ra1 = SCM_CAR (ras);
1820 SCM args, *ve = &ras;
1821 scm_sizet k, i1 = SCM_ARRAY_BASE (ra1);
1822 long inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1823 ra1 = SCM_ARRAY_V (ra1);
1824 ras = SCM_CDR (ras);
1825 if SCM_NULLP
1826 (ras)
1827 ras = scm_nullvect;
1828 else
1829 {
1830 ras = scm_vector (ras);
1831 ve = SCM_VELTS (ras);
1832 }
1833 for (; i <= n; i++, i0 += inc0, i1 += inc1)
1834 {
1835 args = SCM_EOL;
1836 for (k = SCM_LENGTH (ras); k--;)
1837 args = scm_cons (scm_uniform_vector_ref (ve[k], SCM_MAKINUM (i)), args);
1838 args = scm_cons2 (scm_cvref (ra0, i0, SCM_UNDEFINED), scm_cvref (ra1, i1, SCM_UNDEFINED), args);
1839 scm_apply (proc, args, SCM_EOL);
1840 }
1841 }
1842 return 1;
1843}
1844
1845
1846SCM_PROC(s_array_for_each, "array-for-each", 2, 0, 1, scm_array_for_each);
1847#ifdef __STDC__
1848SCM
1849scm_array_for_each (SCM proc, SCM ra0, SCM lra)
1850#else
1851SCM
1852scm_array_for_each (proc, ra0, lra)
1853 SCM proc;
1854 SCM ra0;
1855 SCM lra;
1856#endif
1857{
1858 SCM_ASSERT (SCM_BOOL_T == scm_procedure_p (proc), proc, SCM_ARG1, s_array_for_each);
1859 scm_ramapc (rafe, proc, ra0, lra, s_array_for_each);
1860 return SCM_UNSPECIFIED;
1861}
1862
1863SCM_PROC(s_array_index_map_x, "array-index-map!", 2, 0, 0, scm_array_index_map_x);
1864#ifdef __STDC__
1865SCM
1866scm_array_index_map_x (SCM ra, SCM proc)
1867#else
1868SCM
1869scm_array_index_map_x (ra, proc)
1870 SCM ra;
1871 SCM proc;
1872#endif
1873{
1874 scm_sizet i;
1875 SCM_ASSERT (SCM_NIMP (ra), ra, SCM_ARG1, s_array_index_map_x);
1876 SCM_ASSERT (SCM_BOOL_T == scm_procedure_p (proc), proc, SCM_ARG2, s_array_index_map_x);
1877 switch SCM_TYP7
1878 (ra)
1879 {
1880 default:
1881 badarg:scm_wta (ra, (char *) SCM_ARG1, s_array_index_map_x);
1882 case scm_tc7_vector:
1883 {
1884 SCM *ve = SCM_VELTS (ra);
1885 for (i = 0; i < SCM_LENGTH (ra); i++)
1886 ve[i] = scm_apply (proc, SCM_MAKINUM (i), scm_listofnull);
1887 return SCM_UNSPECIFIED;
1888 }
1889 case scm_tc7_string:
1890 case scm_tc7_bvect:
1891 case scm_tc7_uvect:
1892 case scm_tc7_ivect:
1893 case scm_tc7_fvect:
1894 case scm_tc7_dvect:
1895 case scm_tc7_cvect:
1896 for (i = 0; i < SCM_LENGTH (ra); i++)
1897 scm_array_set_x (ra, scm_apply (proc, SCM_MAKINUM (i), scm_listofnull), SCM_MAKINUM (i));
1898 return SCM_UNSPECIFIED;
1899 case scm_tc7_smob:
1900 SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
1901 {
1902 SCM args = SCM_EOL;
1903 SCM inds = scm_make_uve (SCM_ARRAY_NDIM (ra), SCM_MAKINUM (-1L));
1904 long *vinds = SCM_VELTS (inds);
1905 int j, k, kmax = SCM_ARRAY_NDIM (ra) - 1;
1906 for (k = 0; k <= kmax; k++)
1907 vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd;
1908 k = kmax;
1909 do
1910 {
1911 if (k == kmax)
1912 {
1913 vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd;
1914 i = cind (ra, inds);
1915 for (; vinds[k] <= SCM_ARRAY_DIMS (ra)[k].ubnd; vinds[k]++)
1916 {
1917 for (j = kmax + 1, args = SCM_EOL; j--;)
1918 args = scm_cons (SCM_MAKINUM (vinds[j]), args);
1919 scm_array_set_x (SCM_ARRAY_V (ra), scm_apply (proc, args, SCM_EOL), SCM_MAKINUM (i));
1920 i += SCM_ARRAY_DIMS (ra)[k].inc;
1921 }
1922 k--;
1923 continue;
1924 }
1925 if (vinds[k] < SCM_ARRAY_DIMS (ra)[k].ubnd)
1926 {
1927 vinds[k]++;
1928 k++;
1929 continue;
1930 }
1931 vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd - 1;
1932 k--;
1933 }
1934 while (k >= 0);
1935 return SCM_UNSPECIFIED;
1936 }
1937 }
1938}
1939
1940#ifdef __STDC__
1941static int
1942raeql_1 (SCM ra0, SCM as_equal, SCM ra1)
1943#else
1944static int
1945raeql_1 (ra0, as_equal, ra1)
1946 SCM ra0;
1947 SCM as_equal;
1948 SCM ra1;
1949#endif
1950{
1951 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1952 scm_sizet i0 = 0, i1 = 0;
1953 long inc0 = 1, inc1 = 1;
1954 scm_sizet n = SCM_LENGTH (ra0);
1955 ra1 = SCM_CAR (ra1);
1956 if SCM_ARRAYP
1957 (ra0)
1958 {
1959 n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1960 i0 = SCM_ARRAY_BASE (ra0);
1961 inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1962 ra0 = SCM_ARRAY_V (ra0);
1963 }
1964 if SCM_ARRAYP
1965 (ra1)
1966 {
1967 i1 = SCM_ARRAY_BASE (ra1);
1968 inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1969 ra1 = SCM_ARRAY_V (ra1);
1970 }
1971 switch SCM_TYP7
1972 (ra0)
1973 {
1974 case scm_tc7_vector:
1975 default:
1976 for (; n--; i0 += inc0, i1 += inc1)
1977 {
1978 if SCM_FALSEP
1979 (as_equal)
1980 {
1981 if SCM_FALSEP
1982 (scm_array_equal_p (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)))
1983 return 0;
1984 }
1985 else if SCM_FALSEP
1986 (scm_equal_p (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)))
1987 return 0;
1988 }
1989 return 1;
1990 case scm_tc7_string:
1991 {
1992 char *v0 = SCM_CHARS (ra0) + i0;
1993 char *v1 = SCM_CHARS (ra1) + i1;
1994 for (; n--; v0 += inc0, v1 += inc1)
1995 if (*v0 != *v1)
1996 return 0;
1997 return 1;
1998 }
1999 case scm_tc7_bvect:
2000 for (; n--; i0 += inc0, i1 += inc1)
2001 if (BVE_REF (ra0, i0) != BVE_REF (ra1, i1))
2002 return 0;
2003 return 1;
2004 case scm_tc7_uvect:
2005 case scm_tc7_ivect:
2006 {
2007 long *v0 = (long *) SCM_VELTS (ra0) + i0;
2008 long *v1 = (long *) SCM_VELTS (ra1) + i1;
2009 for (; n--; v0 += inc0, v1 += inc1)
2010 if (*v0 != *v1)
2011 return 0;
2012 return 1;
2013 }
2014#ifdef SCM_FLOATS
2015#ifdef SCM_SINGLES
2016 case scm_tc7_fvect:
2017 {
2018 float *v0 = (float *) SCM_VELTS (ra0) + i0;
2019 float *v1 = (float *) SCM_VELTS (ra1) + i1;
2020 for (; n--; v0 += inc0, v1 += inc1)
2021 if (*v0 != *v1)
2022 return 0;
2023 return 1;
2024 }
2025#endif /* SCM_SINGLES */
2026 case scm_tc7_dvect:
2027 {
2028 double *v0 = (double *) SCM_VELTS (ra0) + i0;
2029 double *v1 = (double *) SCM_VELTS (ra1) + i1;
2030 for (; n--; v0 += inc0, v1 += inc1)
2031 if (*v0 != *v1)
2032 return 0;
2033 return 1;
2034 }
2035 case scm_tc7_cvect:
2036 {
2037 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0) + i0;
2038 double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1) + i1;
2039 for (; n--; v0 += inc0, v1 += inc1)
2040 {
2041 if ((*v0)[0] != (*v1)[0])
2042 return 0;
2043 if ((*v0)[1] != (*v1)[1])
2044 return 0;
2045 }
2046 return 1;
2047 }
2048#endif /* SCM_FLOATS */
2049 }
2050}
2051
2052
2053#ifdef __STDC__
2054static int
2055raeql (SCM ra0, SCM as_equal, SCM ra1)
2056#else
2057static int
2058raeql (ra0, as_equal, ra1)
2059 SCM ra0;
2060 SCM as_equal;
2061 SCM ra1;
2062#endif
2063{
2064 SCM v0 = ra0, v1 = ra1;
2065 scm_array_dim dim0, dim1;
2066 scm_array_dim *s0 = &dim0, *s1 = &dim1;
2067 scm_sizet bas0 = 0, bas1 = 0;
2068 int k, unroll = 1, vlen = 1, ndim = 1;
2069 if SCM_ARRAYP
2070 (ra0)
2071 {
2072 ndim = SCM_ARRAY_NDIM (ra0);
2073 s0 = SCM_ARRAY_DIMS (ra0);
2074 bas0 = SCM_ARRAY_BASE (ra0);
2075 v0 = SCM_ARRAY_V (ra0);
2076 }
2077 else
2078 {
2079 s0->inc = 1;
2080 s0->lbnd = 0;
2081 s0->ubnd = SCM_LENGTH (v0) - 1;
2082 unroll = 0;
2083 }
2084 if SCM_ARRAYP
2085 (ra1)
2086 {
2087 if (ndim != SCM_ARRAY_NDIM (ra1))
2088 return 0;
2089 s1 = SCM_ARRAY_DIMS (ra1);
2090 bas1 = SCM_ARRAY_BASE (ra1);
2091 v1 = SCM_ARRAY_V (ra1);
2092 }
2093 else
2094 {
2095 if (1 != ndim)
2096 return SCM_BOOL_F;
2097 s1->inc = 1;
2098 s1->lbnd = 0;
2099 s1->ubnd = SCM_LENGTH (v1) - 1;
2100 unroll = 0;
2101 }
2102 if (SCM_TYP7 (v0) != SCM_TYP7 (v1))
2103 return 0;
2104 for (k = ndim; k--;)
2105 {
2106 if (s0[k].lbnd != s1[k].lbnd || s0[k].ubnd != s1[k].ubnd)
2107 return 0;
2108 if (unroll)
2109 {
2110 unroll = (s0[k].inc == s1[k].inc);
2111 vlen *= s0[k].ubnd - s1[k].lbnd + 1;
2112 }
2113 }
2114 if (unroll && bas0 == bas1 && v0 == v1)
2115 return SCM_BOOL_T;
2116 return scm_ramapc (raeql_1, as_equal, ra0, scm_cons (ra1, SCM_EOL), "");
2117}
2118
2119#ifdef __STDC__
2120SCM
2121scm_raequal (SCM ra0, SCM ra1)
2122#else
2123SCM
2124scm_raequal (ra0, ra1)
2125 SCM ra0;
2126 SCM ra1;
2127#endif
2128{
2129 return (raeql (ra0, SCM_BOOL_T, ra1) ? SCM_BOOL_T : SCM_BOOL_F);
2130}
2131
2132static char s_array_equal_p[] = "array-equal?";
2133
2134#ifdef __STDC__
2135SCM
2136scm_array_equal_p (SCM ra0, SCM ra1)
2137#else
2138SCM
2139scm_array_equal_p (ra0, ra1)
2140 SCM ra0;
2141 SCM ra1;
2142#endif
2143{
2144 if (SCM_IMP (ra0) || SCM_IMP (ra1))
2145 callequal:return scm_equal_p (ra0, ra1);
2146 switch SCM_TYP7
2147 (ra0)
2148 {
2149 default:
2150 goto callequal;
2151 case scm_tc7_bvect:
2152 case scm_tc7_string:
2153 case scm_tc7_uvect:
2154 case scm_tc7_ivect:
2155 case scm_tc7_fvect:
2156 case scm_tc7_dvect:
2157 case scm_tc7_cvect:
2158 case scm_tc7_vector:
2159 break;
2160 case scm_tc7_smob:
2161 if (!SCM_ARRAYP (ra0))
2162 goto callequal;
2163 }
2164 switch SCM_TYP7
2165 (ra1)
2166 {
2167 default:
2168 goto callequal;
2169 case scm_tc7_bvect:
2170 case scm_tc7_string:
2171 case scm_tc7_uvect:
2172 case scm_tc7_ivect:
2173 case scm_tc7_fvect:
2174 case scm_tc7_dvect:
2175 case scm_tc7_cvect:
2176 case scm_tc7_vector:
2177 break;
2178 case scm_tc7_smob:
2179 if (!SCM_ARRAYP (ra1))
2180 goto callequal;
2181 }
2182 return (raeql (ra0, SCM_BOOL_F, ra1) ? SCM_BOOL_T : SCM_BOOL_F);
2183}
2184
2185
2186
2187
2188/* These tables are a kluge that will not scale well when more
2189 * vectorized subrs are added. It is tempting to steal some bits from
2190 * the SCM_CAR of all subrs (like those selected by SCM_SMOBNUM) to hold an
2191 * offset into a table of vectorized subrs.
2192 */
2193
2194static ra_iproc ra_rpsubrs[] =
2195{
2196 {"=", SCM_UNDEFINED, scm_ra_eqp},
2197 {"<", SCM_UNDEFINED, scm_ra_lessp},
2198 {"<=", SCM_UNDEFINED, scm_ra_leqp},
2199 {">", SCM_UNDEFINED, scm_ra_grp},
2200 {">=", SCM_UNDEFINED, scm_ra_greqp},
2201 {0, 0, 0}
2202};
2203
2204static ra_iproc ra_asubrs[] =
2205{
2206 {"+", SCM_UNDEFINED, scm_ra_sum},
2207 {"-", SCM_UNDEFINED, scm_ra_difference},
2208 {"*", SCM_UNDEFINED, scm_ra_product},
2209 {"/", SCM_UNDEFINED, scm_ra_divide},
2210 {0, 0, 0}
2211};
2212
2213static void init_raprocs (subra)
2214 ra_iproc *subra;
2215{
2216 for (; subra->name; subra++)
2217 subra->sproc = SCM_CDR (scm_intern (subra->name, strlen (subra->name)));
2218}
2219
2220#ifdef __STDC__
2221void
2222scm_init_ramap (void)
2223#else
2224void
2225scm_init_ramap ()
2226#endif
2227{
2228 init_raprocs (ra_rpsubrs);
2229 init_raprocs (ra_asubrs);
2230 scm_make_subr (s_array_equal_p, scm_tc7_rpsubr, scm_array_equal_p);
2231 scm_smobs[0x0ff & (scm_tc16_array >> 8)].equalp = scm_raequal;
2232#include "ramap.x"
2233 scm_add_feature (s_array_for_each);
2234}
2235
2236#endif /* ARRAYS */