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