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