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