revert the ill-considered part of 2001-05-23 changes
[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
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
1be6b49c 169static scm_bits_t
1bbd0b84 170cind (SCM ra, SCM inds)
0f2d19dd 171{
1be6b49c 172 scm_bits_t i;
0f2d19dd 173 int k;
1be6b49c 174 scm_bits_t *ve = (scm_bits_t *) 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;
1be6b49c
ML
196 scm_array_dim_t dims;
197 scm_array_dim_t *s0 = &dims;
198 scm_array_dim_t *s1;
199 scm_bits_t bas0 = 0;
0f2d19dd
JB
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 257 {
1be6b49c 258 scm_bits_t length;
b226e5f6
DH
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;
1be6b49c 325 scm_bits_t *vinds;
0f2d19dd
JB
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 {
1be6b49c 342 scm_bits_t 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 {
1be6b49c 400 scm_bits_t 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));
1be6b49c 432 vinds = (scm_bits_t *) SCM_VELTS (inds);
c209c88e
GB
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{
1be6b49c
ML
481 scm_bits_t i;
482 scm_bits_t n = SCM_ARRAY_DIMS (ra)->ubnd - SCM_ARRAY_DIMS (ra)->lbnd + 1;
483 scm_bits_t inc = SCM_ARRAY_DIMS (ra)->inc;
484 scm_bits_t 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 */
1be6b49c
ML
514 scm_bits_t *ve = (scm_bits_t *) SCM_VELTS (ra);
515 if (1 == inc && (n >= SCM_BITS_LENGTH || n == SCM_BITVECTOR_LENGTH (ra)))
5c11cc9d 516 {
1be6b49c 517 i = base / SCM_BITS_LENGTH;
4260a7fc 518 if (SCM_FALSEP (fill))
5c11cc9d 519 {
1be6b49c
ML
520 if (base % SCM_BITS_LENGTH) /* leading partial word */
521 ve[i++] &= ~(~0L << (base % SCM_BITS_LENGTH));
522 for (; i < (base + n) / SCM_BITS_LENGTH; i++)
5c11cc9d 523 ve[i] = 0L;
1be6b49c
ML
524 if ((base + n) % SCM_BITS_LENGTH) /* trailing partial word */
525 ve[i] &= (~0L << ((base + n) % SCM_BITS_LENGTH));
5c11cc9d 526 }
9a09deb1 527 else if (SCM_EQ_P (fill, SCM_BOOL_T))
5c11cc9d 528 {
1be6b49c
ML
529 if (base % SCM_BITS_LENGTH)
530 ve[i++] |= ~0L << (base % SCM_BITS_LENGTH);
531 for (; i < (base + n) / SCM_BITS_LENGTH; i++)
5c11cc9d 532 ve[i] = ~0L;
1be6b49c
ML
533 if ((base + n) % SCM_BITS_LENGTH)
534 ve[i] |= ~(~0L << ((base + n) % SCM_BITS_LENGTH));
5c11cc9d
GH
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 542 for (i = base; n--; i += inc)
1be6b49c 543 ve[i / SCM_BITS_LENGTH] &= ~(1L << (i % SCM_BITS_LENGTH));
9a09deb1 544 else if (SCM_EQ_P (fill, SCM_BOOL_T))
5c11cc9d 545 for (i = base; n--; i += inc)
1be6b49c 546 ve[i / SCM_BITS_LENGTH] |= (1L << (i % SCM_BITS_LENGTH));
5c11cc9d
GH
547 else
548 goto badarg2;
549 }
550 break;
551 }
552 case scm_tc7_uvect:
1bbd0b84 553 { /* scope */
e4b265d8 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 562 { /* scope */
e4b265d8 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 584 { /* scope */
e4b265d8 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 639{
1be6b49c
ML
640 scm_bits_t n = (SCM_ARRAY_DIMS (src)->ubnd - SCM_ARRAY_DIMS (src)->lbnd + 1);
641 scm_bits_t inc_d, inc_s = SCM_ARRAY_DIMS (src)->inc;
642 scm_bits_t i_d, i_s = SCM_ARRAY_BASE (src);
0f2d19dd
JB
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 676 goto gencase;
1be6b49c
ML
677 if (1 == inc_d && 1 == inc_s && i_s % SCM_BITS_LENGTH == i_d % SCM_BITS_LENGTH
678 && n >= SCM_BITS_LENGTH)
c209c88e 679 {
1be6b49c
ML
680 scm_bits_t *sv = (scm_bits_t *) SCM_VELTS (src);
681 scm_bits_t *dv = (scm_bits_t *) SCM_VELTS (dst);
682 sv += i_s / SCM_BITS_LENGTH;
683 dv += i_d / SCM_BITS_LENGTH;
684 if (i_s % SCM_BITS_LENGTH)
c209c88e 685 { /* leading partial word */
1be6b49c 686 *dv = (*dv & ~(~0L << (i_s % SCM_BITS_LENGTH))) | (*sv & (~0L << (i_s % SCM_BITS_LENGTH)));
c209c88e
GB
687 dv++;
688 sv++;
1be6b49c 689 n -= SCM_BITS_LENGTH - (i_s % SCM_BITS_LENGTH);
c209c88e 690 }
5e4a4d09 691 IVDEP (src != dst,
1be6b49c 692 for (; n >= SCM_BITS_LENGTH; n -= SCM_BITS_LENGTH, sv++, dv++)
5e4a4d09 693 *dv = *sv;)
c209c88e
GB
694 if (n) /* trailing partial word */
695 *dv = (*dv & (~0L << n)) | (*sv & ~(~0L << n));
696 }
697 else
698 {
699 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
700 if (SCM_BITVEC_REF(src, i_s))
701 SCM_BITVEC_SET(dst, i_d);
702 else
703 SCM_BITVEC_CLR(dst, i_d);
704 }
705 break;
706 case scm_tc7_uvect:
707 if (scm_tc7_uvect != SCM_TYP7 (src))
708 goto gencase;
709 else
710 {
711 long *d = (long *) SCM_VELTS (dst), *s = (long *) SCM_VELTS (src);
5e4a4d09 712 IVDEP (src != dst,
c209c88e 713 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
5e4a4d09 714 d[i_d] = s[i_s];)
c209c88e
GB
715 break;
716 }
717 case scm_tc7_ivect:
718 if (scm_tc7_uvect != SCM_TYP7 (src) && scm_tc7_ivect != SCM_TYP7 (src))
719 goto gencase;
720 else
721 {
722 long *d = (long *) SCM_VELTS (dst), *s = (long *) SCM_VELTS (src);
5e4a4d09
MD
723 IVDEP (src != dst,
724 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
725 d[i_d] = s[i_s];)
726 break;
c209c88e 727 }
c209c88e
GB
728 case scm_tc7_fvect:
729 {
730 float *d = (float *) SCM_VELTS (dst);
731 float *s = (float *) SCM_VELTS (src);
732 switch SCM_TYP7
733 (src)
0f2d19dd 734 {
c209c88e
GB
735 default:
736 goto gencase;
737 case scm_tc7_ivect:
738 case scm_tc7_uvect:
5e4a4d09
MD
739 IVDEP (src != dst,
740 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
741 d[i_d] = ((long *) s)[i_s];)
c209c88e
GB
742 break;
743 case scm_tc7_fvect:
5e4a4d09
MD
744 IVDEP (src != dst,
745 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
746 d[i_d] = s[i_s];)
c209c88e
GB
747 break;
748 case scm_tc7_dvect:
5e4a4d09
MD
749 IVDEP (src !=dst,
750 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
751 d[i_d] = ((double *) s)[i_s];)
752 break;
0f2d19dd
JB
753 }
754 break;
c209c88e 755 }
c209c88e
GB
756 case scm_tc7_dvect:
757 {
758 double *d = (double *) SCM_VELTS (dst);
759 double *s = (double *) SCM_VELTS (src);
760 switch SCM_TYP7
761 (src)
0f2d19dd 762 {
c209c88e
GB
763 default:
764 goto gencase;
765 case scm_tc7_ivect:
766 case scm_tc7_uvect:
5e4a4d09
MD
767 IVDEP (src != dst,
768 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
769 d[i_d] = ((long *) s)[i_s];)
c209c88e
GB
770 break;
771 case scm_tc7_fvect:
5e4a4d09
MD
772 IVDEP (src != dst,
773 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
774 d[i_d] = ((float *) s)[i_s];)
c209c88e
GB
775 break;
776 case scm_tc7_dvect:
5e4a4d09
MD
777 IVDEP (src != dst,
778 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
779 d[i_d] = s[i_s];)
0f2d19dd
JB
780 break;
781 }
c209c88e
GB
782 break;
783 }
784 case scm_tc7_cvect:
785 {
786 double (*d)[2] = (double (*)[2]) SCM_VELTS (dst);
787 double (*s)[2] = (double (*)[2]) SCM_VELTS (src);
788 switch SCM_TYP7
789 (src)
0f2d19dd 790 {
c209c88e
GB
791 default:
792 goto gencase;
793 case scm_tc7_ivect:
794 case scm_tc7_uvect:
5e4a4d09
MD
795 IVDEP (src != dst,
796 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
797 {
798 d[i_d][0] = ((long *) s)[i_s];
799 d[i_d][1] = 0.0;
800 })
0f2d19dd 801 break;
c209c88e 802 case scm_tc7_fvect:
5e4a4d09
MD
803 IVDEP (src != dst,
804 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
805 {
806 d[i_d][0] = ((float *) s)[i_s];
807 d[i_d][1] = 0.0;
808 })
c209c88e
GB
809 break;
810 case scm_tc7_dvect:
5e4a4d09
MD
811 IVDEP (src != dst,
812 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
813 {
814 d[i_d][0] = ((double *) s)[i_s];
815 d[i_d][1] = 0.0;
816 })
c209c88e
GB
817 break;
818 case scm_tc7_cvect:
5e4a4d09
MD
819 IVDEP (src != dst,
820 for (; n-- > 0; i_s += inc_s, i_d += inc_d)
821 {
822 d[i_d][0] = s[i_s][0];
823 d[i_d][1] = s[i_s][1];
824 })
0f2d19dd 825 }
c209c88e 826 break;
0f2d19dd 827 }
c209c88e 828 }
0f2d19dd
JB
829 return 1;
830}
831
832
1bbd0b84 833SCM_REGISTER_PROC(s_array_copy_in_order_x, "array-copy-in-order!", 2, 0, 0, scm_array_copy_x);
1cc91f1b 834
1bbd0b84 835
3b3b36dd 836SCM_DEFINE (scm_array_copy_x, "array-copy!", 2, 0, 0,
c209c88e 837 (SCM src, SCM dst),
09831f94 838 "@deffnx primitive array-copy-in-order! src dst\n"
b380b885
MD
839 "Copies every element from vector or array @var{source} to the\n"
840 "corresponding element of @var{destination}. @var{destination} must have\n"
841 "the same rank as @var{source}, and be at least as large in each\n"
842 "dimension. The order is unspecified.")
1bbd0b84 843#define FUNC_NAME s_scm_array_copy_x
0f2d19dd 844{
c209c88e 845 scm_ramapc (racp, SCM_UNDEFINED, src, scm_cons (dst, SCM_EOL), FUNC_NAME);
0f2d19dd
JB
846 return SCM_UNSPECIFIED;
847}
1bbd0b84 848#undef FUNC_NAME
0f2d19dd
JB
849
850/* Functions callable by ARRAY-MAP! */
851
1cc91f1b 852
0f2d19dd 853int
1bbd0b84 854scm_ra_eqp (SCM ra0, SCM ras)
0f2d19dd
JB
855{
856 SCM ra1 = SCM_CAR (ras), ra2 = SCM_CAR (SCM_CDR (ras));
1be6b49c
ML
857 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
858 scm_bits_t i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
859 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc;
860 scm_bits_t inc1 = SCM_ARRAY_DIMS (ra1)->inc;
861 scm_bits_t inc2 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
862 ra0 = SCM_ARRAY_V (ra0);
863 ra1 = SCM_ARRAY_V (ra1);
864 ra2 = SCM_ARRAY_V (ra2);
865 switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
866 {
867 default:
868 {
869 SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
870 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
871 if (SCM_BITVEC_REF (ra0, i0))
872 if (SCM_FALSEP(scm_eq_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))))
873 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd
JB
874 break;
875 }
876 case scm_tc7_uvect:
fee7ef83
DH
877 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
878 if (SCM_BITVEC_REF (ra0, i0))
879 if (((unsigned long *) SCM_VELTS (ra1))[i1] != ((unsigned long *) SCM_VELTS (ra2))[i2])
880 SCM_BITVEC_CLR (ra0, i0);
881 break;
0f2d19dd
JB
882 case scm_tc7_ivect:
883 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e 884 if (SCM_BITVEC_REF (ra0, i0))
fee7ef83 885 if (((signed long *) SCM_VELTS (ra1))[i1] != ((signed long *) SCM_VELTS (ra2))[i2])
c209c88e 886 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd 887 break;
0f2d19dd
JB
888 case scm_tc7_fvect:
889 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
890 if (SCM_BITVEC_REF (ra0, i0))
891 if (((float *) SCM_VELTS (ra1))[i1] != ((float *) SCM_VELTS (ra2))[i2])
892 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd 893 break;
0f2d19dd
JB
894 case scm_tc7_dvect:
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))[i1] != ((double *) SCM_VELTS (ra2))[i2])
898 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd
JB
899 break;
900 case scm_tc7_cvect:
901 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
902 if (SCM_BITVEC_REF (ra0, i0))
903 if (((double *) SCM_VELTS (ra1))[2 * i1] != ((double *) SCM_VELTS (ra2))[2 * i2] ||
904 ((double *) SCM_VELTS (ra1))[2 * i1 + 1] != ((double *) SCM_VELTS (ra2))[2 * i2 + 1])
905 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd 906 break;
0f2d19dd
JB
907 }
908 return 1;
909}
910
911/* opt 0 means <, nonzero means >= */
1cc91f1b 912
0f2d19dd 913static int
1bbd0b84 914ra_compare (SCM ra0,SCM ra1,SCM ra2,int opt)
0f2d19dd 915{
1be6b49c
ML
916 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
917 scm_bits_t i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
918 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc;
919 scm_bits_t inc1 = SCM_ARRAY_DIMS (ra1)->inc;
920 scm_bits_t inc2 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
921 ra0 = SCM_ARRAY_V (ra0);
922 ra1 = SCM_ARRAY_V (ra1);
923 ra2 = SCM_ARRAY_V (ra2);
924 switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
925 {
926 default:
927 {
928 SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
929 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
930 if (SCM_BITVEC_REF (ra0, i0))
931 if (opt ?
932 SCM_NFALSEP (scm_less_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))) :
933 SCM_FALSEP (scm_less_p (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))))
934 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd
JB
935 break;
936 }
937 case scm_tc7_uvect:
fee7ef83
DH
938 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
939 {
940 if (SCM_BITVEC_REF (ra0, i0))
941 if (opt ?
942 ((unsigned long *) SCM_VELTS (ra1))[i1] < ((unsigned long *) SCM_VELTS (ra2))[i2] :
943 ((unsigned long *) SCM_VELTS (ra1))[i1] >= ((unsigned long *) SCM_VELTS (ra2))[i2])
944 SCM_BITVEC_CLR (ra0, i0);
945 }
946 break;
0f2d19dd
JB
947 case scm_tc7_ivect:
948 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
949 {
c209c88e
GB
950 if (SCM_BITVEC_REF (ra0, i0))
951 if (opt ?
fee7ef83
DH
952 ((signed long *) SCM_VELTS (ra1))[i1] < ((signed long *) SCM_VELTS (ra2))[i2] :
953 ((signed long *) SCM_VELTS (ra1))[i1] >= ((signed long *) SCM_VELTS (ra2))[i2])
c209c88e 954 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd
JB
955 }
956 break;
0f2d19dd
JB
957 case scm_tc7_fvect:
958 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
959 if (SCM_BITVEC_REF(ra0, i0))
960 if (opt ?
961 ((float *) SCM_VELTS (ra1))[i1] < ((float *) SCM_VELTS (ra2))[i2] :
962 ((float *) SCM_VELTS (ra1))[i1] >= ((float *) SCM_VELTS (ra2))[i2])
963 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd 964 break;
0f2d19dd
JB
965 case scm_tc7_dvect:
966 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
967 if (SCM_BITVEC_REF (ra0, i0))
968 if (opt ?
969 ((double *) SCM_VELTS (ra1))[i1] < ((double *) SCM_VELTS (ra2))[i2] :
970 ((double *) SCM_VELTS (ra1))[i1] >= ((double *) SCM_VELTS (ra2))[i2])
971 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd 972 break;
0f2d19dd
JB
973 }
974 return 1;
975}
976
977
1cc91f1b 978
0f2d19dd 979int
1bbd0b84 980scm_ra_lessp (SCM ra0, SCM ras)
0f2d19dd
JB
981{
982 return ra_compare (ra0, SCM_CAR (ras), SCM_CAR (SCM_CDR (ras)), 0);
983}
984
1cc91f1b 985
0f2d19dd 986int
1bbd0b84 987scm_ra_leqp (SCM ra0, SCM ras)
0f2d19dd
JB
988{
989 return ra_compare (ra0, SCM_CAR (SCM_CDR (ras)), SCM_CAR (ras), 1);
990}
991
1cc91f1b 992
0f2d19dd 993int
1bbd0b84 994scm_ra_grp (SCM ra0, SCM ras)
0f2d19dd
JB
995{
996 return ra_compare (ra0, SCM_CAR (SCM_CDR (ras)), SCM_CAR (ras), 0);
997}
998
1cc91f1b 999
0f2d19dd 1000int
1bbd0b84 1001scm_ra_greqp (SCM ra0, SCM ras)
0f2d19dd
JB
1002{
1003 return ra_compare (ra0, SCM_CAR (ras), SCM_CAR (SCM_CDR (ras)), 1);
1004}
1005
1006
0f2d19dd 1007int
1bbd0b84 1008scm_ra_sum (SCM ra0, SCM ras)
0f2d19dd 1009{
1be6b49c
ML
1010 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1011 scm_bits_t i0 = SCM_ARRAY_BASE (ra0);
1012 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc;
0f2d19dd 1013 ra0 = SCM_ARRAY_V (ra0);
ff467021 1014 if (SCM_NNULLP(ras))
c209c88e
GB
1015 {
1016 SCM ra1 = SCM_CAR (ras);
1be6b49c
ML
1017 scm_bits_t i1 = SCM_ARRAY_BASE (ra1);
1018 scm_bits_t inc1 = SCM_ARRAY_DIMS (ra1)->inc;
c209c88e
GB
1019 ra1 = SCM_ARRAY_V (ra1);
1020 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
1021 {
1022 default:
0f2d19dd 1023 {
c209c88e
GB
1024 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1025 for (; n-- > 0; i0 += inc0, i1 += inc1)
1026 scm_array_set_x (ra0, scm_sum (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
1027 SCM_MAKINUM (i0));
1028 break;
1029 }
1030 case scm_tc7_uvect:
1031 case scm_tc7_ivect:
1032 BINARY_ELTS_CODE( +=, long);
c209c88e
GB
1033 case scm_tc7_fvect:
1034 BINARY_ELTS_CODE( +=, float);
c209c88e
GB
1035 case scm_tc7_dvect:
1036 BINARY_ELTS_CODE( +=, double);
1037 case scm_tc7_cvect:
1038 BINARY_PAIR_ELTS_CODE( +=, double);
c209c88e
GB
1039 }
1040 }
0f2d19dd
JB
1041 return 1;
1042}
1043
1044
1cc91f1b 1045
0f2d19dd 1046int
1bbd0b84 1047scm_ra_difference (SCM ra0, SCM ras)
0f2d19dd 1048{
1be6b49c
ML
1049 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1050 scm_bits_t i0 = SCM_ARRAY_BASE (ra0);
1051 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc;
0f2d19dd 1052 ra0 = SCM_ARRAY_V (ra0);
ff467021 1053 if (SCM_NULLP (ras))
c209c88e
GB
1054 {
1055 switch (SCM_TYP7 (ra0))
1056 {
1057 default:
1058 {
1059 SCM e0 = SCM_UNDEFINED;
1060 for (; n-- > 0; i0 += inc0)
1061 scm_array_set_x (ra0,
1062 scm_difference (RVREF (ra0, i0, e0), SCM_UNDEFINED),
1063 SCM_MAKINUM (i0));
1064 break;
1065 }
c209c88e
GB
1066 case scm_tc7_fvect:
1067 UNARY_ELTS_CODE( = -, float);
c209c88e
GB
1068 case scm_tc7_dvect:
1069 UNARY_ELTS_CODE( = -, double);
1070 case scm_tc7_cvect:
1071 UNARY_PAIR_ELTS_CODE( = -, double);
c209c88e
GB
1072 }
1073 }
0f2d19dd
JB
1074 else
1075 {
1076 SCM ra1 = SCM_CAR (ras);
1be6b49c
ML
1077 scm_bits_t i1 = SCM_ARRAY_BASE (ra1);
1078 scm_bits_t inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
1079 ra1 = SCM_ARRAY_V (ra1);
1080 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
1081 {
1082 default:
1083 {
1084 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1085 for (; n-- > 0; i0 += inc0, i1 += inc1)
1086 scm_array_set_x (ra0, scm_difference (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)), SCM_MAKINUM (i0));
1087 break;
1088 }
0f2d19dd 1089 case scm_tc7_fvect:
c209c88e 1090 BINARY_ELTS_CODE( -=, float);
0f2d19dd 1091 case scm_tc7_dvect:
c209c88e 1092 BINARY_ELTS_CODE( -=, double);
0f2d19dd 1093 case scm_tc7_cvect:
c209c88e 1094 BINARY_PAIR_ELTS_CODE( -=, double);
0f2d19dd
JB
1095 }
1096 }
1097 return 1;
1098}
1099
1100
1cc91f1b 1101
0f2d19dd 1102int
1bbd0b84 1103scm_ra_product (SCM ra0, SCM ras)
0f2d19dd 1104{
1be6b49c
ML
1105 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1106 scm_bits_t i0 = SCM_ARRAY_BASE (ra0);
1107 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc;
0f2d19dd 1108 ra0 = SCM_ARRAY_V (ra0);
ff467021 1109 if (SCM_NNULLP (ras))
c209c88e
GB
1110 {
1111 SCM ra1 = SCM_CAR (ras);
1be6b49c
ML
1112 scm_bits_t i1 = SCM_ARRAY_BASE (ra1);
1113 scm_bits_t inc1 = SCM_ARRAY_DIMS (ra1)->inc;
c209c88e
GB
1114 ra1 = SCM_ARRAY_V (ra1);
1115 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
1116 {
1117 default:
0f2d19dd 1118 {
c209c88e
GB
1119 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1120 for (; n-- > 0; i0 += inc0, i1 += inc1)
1121 scm_array_set_x (ra0, scm_product (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
1122 SCM_MAKINUM (i0));
1123 break;
1124 }
1125 case scm_tc7_uvect:
1126 case scm_tc7_ivect:
1127 BINARY_ELTS_CODE( *=, long);
c209c88e
GB
1128 case scm_tc7_fvect:
1129 BINARY_ELTS_CODE( *=, float);
c209c88e
GB
1130 case scm_tc7_dvect:
1131 BINARY_ELTS_CODE( *=, double);
1132 case scm_tc7_cvect:
1133 {
1134 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
1135 register double r;
1136 double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1);
1137 IVDEP (ra0 != ra1,
1138 for (; n-- > 0; i0 += inc0, i1 += inc1)
1139 {
1140 r = v0[i0][0] * v1[i1][0] - v0[i0][1] * v1[i1][1];
1141 v0[i0][1] = v0[i0][0] * v1[i1][1] + v0[i0][1] * v1[i1][0];
1142 v0[i0][0] = r;
1143 }
1144 );
1145 break;
0f2d19dd 1146 }
c209c88e
GB
1147 }
1148 }
0f2d19dd
JB
1149 return 1;
1150}
1151
1cc91f1b 1152
0f2d19dd 1153int
1bbd0b84 1154scm_ra_divide (SCM ra0, SCM ras)
0f2d19dd 1155{
1be6b49c
ML
1156 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1157 scm_bits_t i0 = SCM_ARRAY_BASE (ra0);
1158 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc;
0f2d19dd 1159 ra0 = SCM_ARRAY_V (ra0);
ff467021 1160 if (SCM_NULLP (ras))
c209c88e
GB
1161 {
1162 switch (SCM_TYP7 (ra0))
1163 {
1164 default:
1165 {
1166 SCM e0 = SCM_UNDEFINED;
1167 for (; n-- > 0; i0 += inc0)
1168 scm_array_set_x (ra0, scm_divide (RVREF (ra0, i0, e0), SCM_UNDEFINED), SCM_MAKINUM (i0));
1169 break;
1170 }
c209c88e
GB
1171 case scm_tc7_fvect:
1172 UNARY_ELTS_CODE( = 1.0 / , float);
c209c88e
GB
1173 case scm_tc7_dvect:
1174 UNARY_ELTS_CODE( = 1.0 / , double);
1175 case scm_tc7_cvect:
1176 {
1177 register double d;
1178 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
1179 for (; n-- > 0; i0 += inc0)
0f2d19dd 1180 {
c209c88e
GB
1181 d = v0[i0][0] * v0[i0][0] + v0[i0][1] * v0[i0][1];
1182 v0[i0][0] /= d;
1183 v0[i0][1] /= -d;
0f2d19dd 1184 }
c209c88e
GB
1185 break;
1186 }
c209c88e
GB
1187 }
1188 }
0f2d19dd
JB
1189 else
1190 {
1191 SCM ra1 = SCM_CAR (ras);
1be6b49c
ML
1192 scm_bits_t i1 = SCM_ARRAY_BASE (ra1);
1193 scm_bits_t inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
1194 ra1 = SCM_ARRAY_V (ra1);
1195 switch (SCM_TYP7 (ra0) == SCM_TYP7 (ra1) ? SCM_TYP7 (ra0) : 0)
1196 {
1197 default:
1198 {
1199 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1200 for (; n-- > 0; i0 += inc0, i1 += inc1)
1201 scm_array_set_x (ra0, scm_divide (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)), SCM_MAKINUM (i0));
1202 break;
1203 }
0f2d19dd 1204 case scm_tc7_fvect:
c209c88e 1205 BINARY_ELTS_CODE( /=, float);
0f2d19dd 1206 case scm_tc7_dvect:
c209c88e 1207 BINARY_ELTS_CODE( /=, double);
0f2d19dd
JB
1208 case scm_tc7_cvect:
1209 {
1210 register double d, r;
1211 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0);
1212 double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1);
1213 IVDEP (ra0 != ra1,
1214 for (; n-- > 0; i0 += inc0, i1 += inc1)
c209c88e
GB
1215 {
1216 d = v1[i1][0] * v1[i1][0] + v1[i1][1] * v1[i1][1];
1217 r = (v0[i0][0] * v1[i1][0] + v0[i0][1] * v1[i1][1]) / d;
1218 v0[i0][1] = (v0[i0][1] * v1[i1][0] - v0[i0][0] * v1[i1][1]) / d;
1219 v0[i0][0] = r;
1220 }
0f2d19dd
JB
1221 )
1222 break;
1223 }
0f2d19dd
JB
1224 }
1225 }
1226 return 1;
1227}
1228
1cc91f1b 1229
0f2d19dd 1230int
1bbd0b84 1231scm_array_identity (SCM dst, SCM src)
0f2d19dd
JB
1232{
1233 return racp (SCM_CAR (src), scm_cons (dst, SCM_EOL));
1234}
1235
1236
1cc91f1b 1237
0f2d19dd 1238static int
1bbd0b84 1239ramap (SCM ra0,SCM proc,SCM ras)
0f2d19dd 1240{
1be6b49c
ML
1241 scm_bits_t i = SCM_ARRAY_DIMS (ra0)->lbnd;
1242 scm_bits_t inc = SCM_ARRAY_DIMS (ra0)->inc;
1243 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd;
1244 scm_bits_t base = SCM_ARRAY_BASE (ra0) - i * inc;
0f2d19dd 1245 ra0 = SCM_ARRAY_V (ra0);
ff467021 1246 if (SCM_NULLP (ras))
c209c88e
GB
1247 for (; i <= n; i++)
1248 scm_array_set_x (ra0, scm_apply (proc, SCM_EOL, SCM_EOL), SCM_MAKINUM (i * inc + base));
0f2d19dd
JB
1249 else
1250 {
1251 SCM ra1 = SCM_CAR (ras);
1252 SCM args, *ve = &ras;
1be6b49c
ML
1253 scm_bits_t k, i1 = SCM_ARRAY_BASE (ra1);
1254 scm_bits_t inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
1255 ra1 = SCM_ARRAY_V (ra1);
1256 ras = SCM_CDR (ras);
ff467021 1257 if (SCM_NULLP(ras))
c209c88e 1258 ras = scm_nullvect;
0f2d19dd
JB
1259 else
1260 {
1261 ras = scm_vector (ras);
1262 ve = SCM_VELTS (ras);
1263 }
1264 for (; i <= n; i++, i1 += inc1)
1265 {
1266 args = SCM_EOL;
b226e5f6 1267 for (k = SCM_INUM (scm_uniform_vector_length (ras)); k--;)
0f2d19dd
JB
1268 args = scm_cons (scm_uniform_vector_ref (ve[k], SCM_MAKINUM (i)), args);
1269 args = scm_cons (scm_cvref (ra1, i1, SCM_UNDEFINED), args);
1270 scm_array_set_x (ra0, scm_apply (proc, args, SCM_EOL), SCM_MAKINUM (i * inc + base));
1271 }
1272 }
1273 return 1;
1274}
1275
1cc91f1b 1276
0f2d19dd 1277static int
1bbd0b84 1278ramap_cxr (SCM ra0,SCM proc,SCM ras)
0f2d19dd
JB
1279{
1280 SCM ra1 = SCM_CAR (ras);
1281 SCM e1 = SCM_UNDEFINED;
1be6b49c
ML
1282 scm_bits_t i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
1283 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1284 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra1)->lbnd + 1;
0f2d19dd
JB
1285 ra0 = SCM_ARRAY_V (ra0);
1286 ra1 = SCM_ARRAY_V (ra1);
ff467021 1287 switch (SCM_TYP7 (ra0))
c209c88e
GB
1288 {
1289 default:
1290 gencase:
1291 for (; n-- > 0; i0 += inc0, i1 += inc1)
1292 scm_array_set_x (ra0, scm_apply (proc, RVREF (ra1, i1, e1), scm_listofnull), SCM_MAKINUM (i0));
1293 break;
c209c88e
GB
1294 case scm_tc7_fvect:
1295 {
1296 float *dst = (float *) SCM_VELTS (ra0);
1297 switch (SCM_TYP7 (ra1))
1298 {
1299 default:
1300 goto gencase;
1301 case scm_tc7_fvect:
1302 for (; n-- > 0; i0 += inc0, i1 += inc1)
1303 dst[i0] = SCM_DSUBRF (proc) ((double) ((float *) SCM_VELTS (ra1))[i1]);
1304 break;
1305 case scm_tc7_uvect:
1306 case scm_tc7_ivect:
1307 for (; n-- > 0; i0 += inc0, i1 += inc1)
f1267706 1308 dst[i0] = SCM_DSUBRF (proc) (SCM_UNPACK (SCM_VELTS (ra1)[i1]));
c209c88e
GB
1309 break;
1310 }
1311 break;
1312 }
c209c88e
GB
1313 case scm_tc7_dvect:
1314 {
1315 double *dst = (double *) SCM_VELTS (ra0);
1316 switch (SCM_TYP7 (ra1))
1317 {
1318 default:
1319 goto gencase;
1320 case scm_tc7_dvect:
1321 for (; n-- > 0; i0 += inc0, i1 += inc1)
1322 dst[i0] = SCM_DSUBRF (proc) (((double *) SCM_VELTS (ra1))[i1]);
1323 break;
1324 case scm_tc7_uvect:
1325 case scm_tc7_ivect:
1326 for (; n-- > 0; i0 += inc0, i1 += inc1)
f1267706 1327 dst[i0] = SCM_DSUBRF (proc) (SCM_UNPACK (SCM_VELTS (ra1)[i1]));
c209c88e
GB
1328 break;
1329 }
1330 break;
0f2d19dd 1331 }
c209c88e 1332 }
0f2d19dd
JB
1333 return 1;
1334}
1335
1336
1cc91f1b 1337
0f2d19dd 1338static int
1bbd0b84 1339ramap_rp (SCM ra0,SCM proc,SCM ras)
0f2d19dd
JB
1340{
1341 SCM ra1 = SCM_CAR (ras), ra2 = SCM_CAR (SCM_CDR (ras));
1342 SCM e1 = SCM_UNDEFINED, e2 = SCM_UNDEFINED;
1be6b49c
ML
1343 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1344 scm_bits_t i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1), i2 = SCM_ARRAY_BASE (ra2);
1345 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1346 scm_bits_t inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1347 scm_bits_t inc2 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
1348 ra0 = SCM_ARRAY_V (ra0);
1349 ra1 = SCM_ARRAY_V (ra1);
1350 ra2 = SCM_ARRAY_V (ra2);
1351 switch (SCM_TYP7 (ra1) == SCM_TYP7 (ra2) ? SCM_TYP7 (ra1) : 0)
1352 {
1353 default:
1354 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
1355 if (SCM_BITVEC_REF (ra0, i0))
1356 if (SCM_FALSEP (SCM_SUBRF (proc) (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2))))
1357 SCM_BITVEC_CLR (ra0, i0);
0f2d19dd
JB
1358 break;
1359 case scm_tc7_uvect:
1360 case scm_tc7_ivect:
1361 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
1362 if (SCM_BITVEC_REF (ra0, i0))
1363 {
f2961ccd
DH
1364 /* DIRK:FIXME:: There should be a way to access the elements
1365 of a cell as raw data. Further: How can we be sure that
1366 the values fit into an inum?
1367 */
1ff2fa6e
DH
1368 SCM n1 = SCM_MAKINUM (((long *) SCM_UNPACK (SCM_CDR (ra1)))[i1]);
1369 SCM n2 = SCM_MAKINUM (((long *) SCM_UNPACK (SCM_CDR (ra2)))[i2]);
f2961ccd 1370 if (SCM_FALSEP (SCM_SUBRF (proc) (n1, n2)));
c209c88e
GB
1371 SCM_BITVEC_CLR (ra0, i0);
1372 }
0f2d19dd 1373 break;
0f2d19dd
JB
1374 case scm_tc7_fvect:
1375 {
950cc72b 1376 SCM a1 = scm_make_real (1.0), a2 = scm_make_real (1.0);
0f2d19dd 1377 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
1378 if (SCM_BITVEC_REF (ra0, i0))
1379 {
950cc72b
MD
1380 SCM_REAL_VALUE (a1) = ((float *) SCM_VELTS (ra1))[i1];
1381 SCM_REAL_VALUE (a2) = ((float *) SCM_VELTS (ra2))[i2];
c209c88e
GB
1382 if (SCM_FALSEP (SCM_SUBRF (proc) (a1, a2)))
1383 SCM_BITVEC_CLR (ra0, i0);
1384 }
0f2d19dd
JB
1385 break;
1386 }
0f2d19dd
JB
1387 case scm_tc7_dvect:
1388 {
f8de44c1
DH
1389 SCM a1 = scm_make_real (1.0 / 3.0);
1390 SCM a2 = scm_make_real (1.0 / 3.0);
0f2d19dd 1391 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
1392 if (SCM_BITVEC_REF (ra0, i0))
1393 {
eb42e2f0
DH
1394 SCM_REAL_VALUE (a1) = ((double *) SCM_VELTS (ra1))[i1];
1395 SCM_REAL_VALUE (a2) = ((double *) SCM_VELTS (ra2))[i2];
c209c88e
GB
1396 if (SCM_FALSEP (SCM_SUBRF (proc) (a1, a2)))
1397 SCM_BITVEC_CLR (ra0, i0);
1398 }
0f2d19dd
JB
1399 break;
1400 }
1401 case scm_tc7_cvect:
1402 {
f8de44c1
DH
1403 SCM a1 = scm_make_complex (1.0, 1.0);
1404 SCM a2 = scm_make_complex (1.0, 1.0);
0f2d19dd 1405 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
c209c88e
GB
1406 if (SCM_BITVEC_REF (ra0, i0))
1407 {
950cc72b
MD
1408 SCM_COMPLEX_REAL (a1) = ((double *) SCM_VELTS (ra1))[2 * i1];
1409 SCM_COMPLEX_IMAG (a1) = ((double *) SCM_VELTS (ra1))[2 * i1 + 1];
1410 SCM_COMPLEX_REAL (a2) = ((double *) SCM_VELTS (ra2))[2 * i2];
1411 SCM_COMPLEX_IMAG (a2) = ((double *) SCM_VELTS (ra2))[2 * i2 + 1];
c209c88e
GB
1412 if (SCM_FALSEP (SCM_SUBRF (proc) (a1, a2)))
1413 SCM_BITVEC_CLR (ra0, i0);
1414 }
0f2d19dd
JB
1415 break;
1416 }
0f2d19dd
JB
1417 }
1418 return 1;
1419}
1420
1421
1cc91f1b 1422
0f2d19dd 1423static int
1bbd0b84 1424ramap_1 (SCM ra0,SCM proc,SCM ras)
0f2d19dd
JB
1425{
1426 SCM ra1 = SCM_CAR (ras);
1427 SCM e1 = SCM_UNDEFINED;
1be6b49c
ML
1428 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1429 scm_bits_t i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
1430 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
1431 ra0 = SCM_ARRAY_V (ra0);
1432 ra1 = SCM_ARRAY_V (ra1);
95f5b0f5 1433 if (scm_tc7_vector == SCM_TYP7 (ra0) || scm_tc7_wvect == SCM_TYP7 (ra0))
0f2d19dd
JB
1434 for (; n-- > 0; i0 += inc0, i1 += inc1)
1435 scm_array_set_x (ra0, SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED)), SCM_MAKINUM (i0));
1436 else
1437 for (; n-- > 0; i0 += inc0, i1 += inc1)
1438 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra1, i1, e1)), SCM_MAKINUM (i0));
1439 return 1;
1440}
1441
1442
1cc91f1b 1443
0f2d19dd 1444static int
1bbd0b84 1445ramap_2o (SCM ra0,SCM proc,SCM ras)
0f2d19dd
JB
1446{
1447 SCM ra1 = SCM_CAR (ras);
1448 SCM e1 = SCM_UNDEFINED;
1be6b49c
ML
1449 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1450 scm_bits_t i0 = SCM_ARRAY_BASE (ra0), i1 = SCM_ARRAY_BASE (ra1);
1451 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc, inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
1452 ra0 = SCM_ARRAY_V (ra0);
1453 ra1 = SCM_ARRAY_V (ra1);
1454 ras = SCM_CDR (ras);
ff467021 1455 if (SCM_NULLP (ras))
c209c88e
GB
1456 {
1457 if (scm_tc7_vector == SCM_TYP7 (ra0)
1458 || scm_tc7_wvect == SCM_TYP7 (ra0))
95f5b0f5 1459
c209c88e
GB
1460 for (; n-- > 0; i0 += inc0, i1 += inc1)
1461 scm_array_set_x (ra0, SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED), SCM_UNDEFINED),
1462 SCM_MAKINUM (i0));
1463 else
1464 for (; n-- > 0; i0 += inc0, i1 += inc1)
1465 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra1, i1, e1), SCM_UNDEFINED),
1466 SCM_MAKINUM (i0));
1467 }
0f2d19dd
JB
1468 else
1469 {
1470 SCM ra2 = SCM_CAR (ras);
1471 SCM e2 = SCM_UNDEFINED;
1be6b49c
ML
1472 scm_bits_t i2 = SCM_ARRAY_BASE (ra2);
1473 scm_bits_t inc2 = SCM_ARRAY_DIMS (ra2)->inc;
0f2d19dd 1474 ra2 = SCM_ARRAY_V (ra2);
95f5b0f5 1475 if (scm_tc7_vector == SCM_TYP7 (ra0) || scm_tc7_wvect == SCM_TYP7 (ra0))
0f2d19dd
JB
1476 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
1477 scm_array_set_x (ra0,
c209c88e
GB
1478 SCM_SUBRF (proc) (scm_cvref (ra1, i1, SCM_UNDEFINED), scm_cvref (ra2, i2, SCM_UNDEFINED)),
1479 SCM_MAKINUM (i0));
0f2d19dd
JB
1480 else
1481 for (; n-- > 0; i0 += inc0, i1 += inc1, i2 += inc2)
1482 scm_array_set_x (ra0,
c209c88e
GB
1483 SCM_SUBRF (proc) (RVREF (ra1, i1, e1), RVREF (ra2, i2, e2)),
1484 SCM_MAKINUM (i0));
0f2d19dd
JB
1485 }
1486 return 1;
1487}
1488
1489
1cc91f1b 1490
0f2d19dd 1491static int
1bbd0b84 1492ramap_a (SCM ra0,SCM proc,SCM ras)
0f2d19dd
JB
1493{
1494 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1be6b49c
ML
1495 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1496 scm_bits_t i0 = SCM_ARRAY_BASE (ra0);
1497 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc;
0f2d19dd 1498 ra0 = SCM_ARRAY_V (ra0);
ff467021 1499 if (SCM_NULLP (ras))
c209c88e
GB
1500 for (; n-- > 0; i0 += inc0)
1501 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra0, i0, e0), SCM_UNDEFINED), SCM_MAKINUM (i0));
0f2d19dd
JB
1502 else
1503 {
1504 SCM ra1 = SCM_CAR (ras);
1be6b49c
ML
1505 scm_bits_t i1 = SCM_ARRAY_BASE (ra1);
1506 scm_bits_t inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
1507 ra1 = SCM_ARRAY_V (ra1);
1508 for (; n-- > 0; i0 += inc0, i1 += inc1)
1509 scm_array_set_x (ra0, SCM_SUBRF (proc) (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1)),
c209c88e 1510 SCM_MAKINUM (i0));
0f2d19dd
JB
1511 }
1512 return 1;
1513}
1514
f5f2dcff 1515
1bbd0b84 1516SCM_REGISTER_PROC(s_array_map_in_order_x, "array-map-in-order!", 2, 0, 1, scm_array_map_x);
1cc91f1b 1517
1bbd0b84 1518
3b3b36dd 1519SCM_DEFINE (scm_array_map_x, "array-map!", 2, 0, 1,
c209c88e 1520 (SCM ra0, SCM proc, SCM lra),
09831f94 1521 "@deffnx primitive array-map-in-order! ra0 proc . lra\n"
b380b885
MD
1522 "@var{array1}, @dots{} must have the same number of dimensions as\n"
1523 "@var{array0} and have a range for each index which includes the range\n"
1524 "for the corresponding index in @var{array0}. @var{proc} is applied to\n"
1525 "each tuple of elements of @var{array1} @dots{} and the result is stored\n"
1526 "as the corresponding element in @var{array0}. The value returned is\n"
1527 "unspecified. The order of application is unspecified.")
1bbd0b84 1528#define FUNC_NAME s_scm_array_map_x
0f2d19dd 1529{
3b3b36dd 1530 SCM_VALIDATE_PROC (2,proc);
af45e3b0 1531 SCM_VALIDATE_REST_ARGUMENT (lra);
0f2d19dd 1532 switch (SCM_TYP7 (proc))
c209c88e
GB
1533 {
1534 default:
1535 gencase:
1536 scm_ramapc (ramap, proc, ra0, lra, FUNC_NAME);
1537 return SCM_UNSPECIFIED;
1538 case scm_tc7_subr_1:
1539 scm_ramapc (ramap_1, proc, ra0, lra, FUNC_NAME);
1540 return SCM_UNSPECIFIED;
1541 case scm_tc7_subr_2:
1542 case scm_tc7_subr_2o:
1543 scm_ramapc (ramap_2o, proc, ra0, lra, FUNC_NAME);
1544 return SCM_UNSPECIFIED;
1545 case scm_tc7_cxr:
1546 if (!SCM_SUBRF (proc))
1547 goto gencase;
1548 scm_ramapc (ramap_cxr, proc, ra0, lra, FUNC_NAME);
1549 return SCM_UNSPECIFIED;
1550 case scm_tc7_rpsubr:
0f2d19dd 1551 {
c209c88e
GB
1552 ra_iproc *p;
1553 if (SCM_FALSEP (scm_array_p (ra0, SCM_BOOL_T)))
0f2d19dd 1554 goto gencase;
c209c88e
GB
1555 scm_array_fill_x (ra0, SCM_BOOL_T);
1556 for (p = ra_rpsubrs; p->name; p++)
fee7ef83 1557 if (SCM_EQ_P (proc, p->sproc))
c209c88e
GB
1558 {
1559 while (SCM_NNULLP (lra) && SCM_NNULLP (SCM_CDR (lra)))
1560 {
1561 scm_ramapc (p->vproc, SCM_UNDEFINED, ra0, lra, FUNC_NAME);
1562 lra = SCM_CDR (lra);
1563 }
1564 return SCM_UNSPECIFIED;
1565 }
1566 while (SCM_NNULLP (lra) && SCM_NNULLP (SCM_CDR (lra)))
1567 {
1568 scm_ramapc (ramap_rp, proc, ra0, lra, FUNC_NAME);
1569 lra = SCM_CDR (lra);
1570 }
0f2d19dd 1571 return SCM_UNSPECIFIED;
c209c88e
GB
1572 }
1573 case scm_tc7_asubr:
1574 if (SCM_NULLP (lra))
1575 {
1576 SCM prot, fill = SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED);
1577 if (SCM_INUMP(fill))
1578 {
1579 prot = scm_array_prototype (ra0);
eb42e2f0 1580 if (SCM_INEXACTP (prot))
f8de44c1 1581 fill = scm_make_real ((double) SCM_INUM (fill));
c209c88e
GB
1582 }
1583
1584 scm_array_fill_x (ra0, fill);
1585 }
1586 else
0f2d19dd 1587 {
c209c88e
GB
1588 SCM tail, ra1 = SCM_CAR (lra);
1589 SCM v0 = (SCM_ARRAYP (ra0) ? SCM_ARRAY_V (ra0) : ra0);
0f2d19dd 1590 ra_iproc *p;
c209c88e
GB
1591 /* Check to see if order might matter.
1592 This might be an argument for a separate
1593 SERIAL-ARRAY-MAP! */
fee7ef83
DH
1594 if (SCM_EQ_P (v0, ra1)
1595 || (SCM_ARRAYP (ra1) && SCM_EQ_P (v0, SCM_ARRAY_V (ra1))))
1596 if (!SCM_EQ_P (ra0, ra1)
1597 || (SCM_ARRAYP(ra0) && !SCM_ARRAY_CONTP(ra0)))
c209c88e
GB
1598 goto gencase;
1599 for (tail = SCM_CDR (lra); SCM_NNULLP (tail); tail = SCM_CDR (tail))
1600 {
1601 ra1 = SCM_CAR (tail);
fee7ef83
DH
1602 if (SCM_EQ_P (v0, ra1)
1603 || (SCM_ARRAYP (ra1) && SCM_EQ_P (v0, SCM_ARRAY_V (ra1))))
c209c88e
GB
1604 goto gencase;
1605 }
1606 for (p = ra_asubrs; p->name; p++)
fee7ef83 1607 if (SCM_EQ_P (proc, p->sproc))
0f2d19dd 1608 {
fee7ef83 1609 if (!SCM_EQ_P (ra0, SCM_CAR (lra)))
c209c88e
GB
1610 scm_ramapc (scm_array_identity, SCM_UNDEFINED, ra0, scm_cons (SCM_CAR (lra), SCM_EOL), FUNC_NAME);
1611 lra = SCM_CDR (lra);
1612 while (1)
0f2d19dd 1613 {
c209c88e
GB
1614 scm_ramapc (p->vproc, SCM_UNDEFINED, ra0, lra, FUNC_NAME);
1615 if (SCM_IMP (lra) || SCM_IMP (SCM_CDR (lra)))
1616 return SCM_UNSPECIFIED;
0f2d19dd
JB
1617 lra = SCM_CDR (lra);
1618 }
0f2d19dd 1619 }
c209c88e
GB
1620 scm_ramapc (ramap_2o, proc, ra0, lra, FUNC_NAME);
1621 lra = SCM_CDR (lra);
1622 if (SCM_NIMP (lra))
1623 for (lra = SCM_CDR (lra); SCM_NIMP (lra); lra = SCM_CDR (lra))
1624 scm_ramapc (ramap_a, proc, ra0, lra, FUNC_NAME);
0f2d19dd 1625 }
c209c88e
GB
1626 return SCM_UNSPECIFIED;
1627 }
0f2d19dd 1628}
1bbd0b84 1629#undef FUNC_NAME
0f2d19dd 1630
1cc91f1b 1631
0f2d19dd 1632static int
1bbd0b84 1633rafe (SCM ra0,SCM proc,SCM ras)
0f2d19dd 1634{
1be6b49c
ML
1635 scm_bits_t i = SCM_ARRAY_DIMS (ra0)->lbnd;
1636 scm_bits_t i0 = SCM_ARRAY_BASE (ra0);
1637 scm_bits_t inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1638 scm_bits_t n = SCM_ARRAY_DIMS (ra0)->ubnd;
0f2d19dd 1639 ra0 = SCM_ARRAY_V (ra0);
ff467021 1640 if (SCM_NULLP (ras))
c209c88e
GB
1641 for (; i <= n; i++, i0 += inc0)
1642 scm_apply (proc, scm_cvref (ra0, i0, SCM_UNDEFINED), scm_listofnull);
0f2d19dd
JB
1643 else
1644 {
1645 SCM ra1 = SCM_CAR (ras);
1646 SCM args, *ve = &ras;
1be6b49c
ML
1647 scm_bits_t k, i1 = SCM_ARRAY_BASE (ra1);
1648 scm_bits_t inc1 = SCM_ARRAY_DIMS (ra1)->inc;
0f2d19dd
JB
1649 ra1 = SCM_ARRAY_V (ra1);
1650 ras = SCM_CDR (ras);
ff467021 1651 if (SCM_NULLP(ras))
c209c88e 1652 ras = scm_nullvect;
0f2d19dd
JB
1653 else
1654 {
1655 ras = scm_vector (ras);
1656 ve = SCM_VELTS (ras);
1657 }
1658 for (; i <= n; i++, i0 += inc0, i1 += inc1)
1659 {
1660 args = SCM_EOL;
b226e5f6 1661 for (k = SCM_INUM (scm_uniform_vector_length (ras)); k--;)
0f2d19dd
JB
1662 args = scm_cons (scm_uniform_vector_ref (ve[k], SCM_MAKINUM (i)), args);
1663 args = scm_cons2 (scm_cvref (ra0, i0, SCM_UNDEFINED), scm_cvref (ra1, i1, SCM_UNDEFINED), args);
1664 scm_apply (proc, args, SCM_EOL);
1665 }
1666 }
1667 return 1;
1668}
1669
1670
3b3b36dd 1671SCM_DEFINE (scm_array_for_each, "array-for-each", 2, 0, 1,
c209c88e 1672 (SCM proc, SCM ra0, SCM lra),
b380b885
MD
1673 "@var{proc} is applied to each tuple of elements of @var{array0} @dots{}\n"
1674 "in row-major order. The value returned is unspecified.")
1bbd0b84 1675#define FUNC_NAME s_scm_array_for_each
0f2d19dd 1676{
3b3b36dd 1677 SCM_VALIDATE_PROC (1,proc);
af45e3b0 1678 SCM_VALIDATE_REST_ARGUMENT (lra);
c209c88e 1679 scm_ramapc (rafe, proc, ra0, lra, FUNC_NAME);
0f2d19dd
JB
1680 return SCM_UNSPECIFIED;
1681}
1bbd0b84 1682#undef FUNC_NAME
0f2d19dd 1683
3b3b36dd 1684SCM_DEFINE (scm_array_index_map_x, "array-index-map!", 2, 0, 0,
c209c88e 1685 (SCM ra, SCM proc),
b380b885
MD
1686 "applies @var{proc} to the indices of each element of @var{array} in\n"
1687 "turn, storing the result in the corresponding element. The value\n"
1688 "returned and the order of application are unspecified.\n\n"
1689 "One can implement @var{array-indexes} as\n"
1e6808ea 1690 "@lisp\n"
b380b885
MD
1691 "(define (array-indexes array)\n"
1692 " (let ((ra (apply make-array #f (array-shape array))))\n"
1693 " (array-index-map! ra (lambda x x))\n"
1694 " ra))\n"
1e6808ea 1695 "@end lisp\n"
b380b885 1696 "Another example:\n"
1e6808ea 1697 "@lisp\n"
b380b885
MD
1698 "(define (apl:index-generator n)\n"
1699 " (let ((v (make-uniform-vector n 1)))\n"
1700 " (array-index-map! v (lambda (i) i))\n"
1701 " v))\n"
1e6808ea 1702 "@end lisp")
1bbd0b84 1703#define FUNC_NAME s_scm_array_index_map_x
0f2d19dd 1704{
1be6b49c 1705 scm_bits_t i;
6b5a304f 1706 SCM_VALIDATE_NIM (1,ra);
3b3b36dd 1707 SCM_VALIDATE_PROC (2,proc);
e42c09cc
RS
1708 switch (SCM_TYP7(ra))
1709 {
1710 default:
276dd677 1711 badarg:SCM_WRONG_TYPE_ARG (1, ra);
e42c09cc
RS
1712 case scm_tc7_vector:
1713 case scm_tc7_wvect:
0f2d19dd 1714 {
e42c09cc 1715 SCM *ve = SCM_VELTS (ra);
b226e5f6 1716 for (i = 0; i < SCM_VECTOR_LENGTH (ra); i++)
e42c09cc
RS
1717 ve[i] = scm_apply (proc, SCM_MAKINUM (i), scm_listofnull);
1718 return SCM_UNSPECIFIED;
1719 }
1720 case scm_tc7_string:
1721 case scm_tc7_byvect:
1722 case scm_tc7_bvect:
1723 case scm_tc7_uvect:
1724 case scm_tc7_ivect:
05f92e0f 1725 case scm_tc7_svect:
5c11cc9d 1726#ifdef HAVE_LONG_LONGS
05f92e0f
JB
1727 case scm_tc7_llvect:
1728#endif
e42c09cc
RS
1729 case scm_tc7_fvect:
1730 case scm_tc7_dvect:
1731 case scm_tc7_cvect:
b226e5f6 1732 {
1be6b49c 1733 scm_bits_t length = SCM_INUM (scm_uniform_vector_length (ra));
b226e5f6
DH
1734 for (i = 0; i < length; i++)
1735 scm_array_set_x (ra, scm_apply (proc, SCM_MAKINUM (i), scm_listofnull),
1736 SCM_MAKINUM (i));
1737 return SCM_UNSPECIFIED;
1738 }
e42c09cc
RS
1739 case scm_tc7_smob:
1740 SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
1741 {
1742 SCM args = SCM_EOL;
1743 SCM inds = scm_make_uve (SCM_ARRAY_NDIM (ra), SCM_MAKINUM (-1L));
1be6b49c 1744 scm_bits_t *vinds = (scm_bits_t *) SCM_VELTS (inds);
e42c09cc
RS
1745 int j, k, kmax = SCM_ARRAY_NDIM (ra) - 1;
1746 if (kmax < 0)
1747 return scm_array_set_x (ra, scm_apply(proc, SCM_EOL, SCM_EOL),
1748 SCM_EOL);
1749 for (k = 0; k <= kmax; k++)
1750 vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd;
1751 k = kmax;
1752 do
1753 {
1754 if (k == kmax)
1755 {
1756 vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd;
1757 i = cind (ra, inds);
1758 for (; vinds[k] <= SCM_ARRAY_DIMS (ra)[k].ubnd; vinds[k]++)
1759 {
1760 for (j = kmax + 1, args = SCM_EOL; j--;)
1761 args = scm_cons (SCM_MAKINUM (vinds[j]), args);
1762 scm_array_set_x (SCM_ARRAY_V (ra),
1763 scm_apply (proc, args, SCM_EOL),
1764 SCM_MAKINUM (i));
1765 i += SCM_ARRAY_DIMS (ra)[k].inc;
1766 }
1767 k--;
1768 continue;
1769 }
1770 if (vinds[k] < SCM_ARRAY_DIMS (ra)[k].ubnd)
1771 {
1772 vinds[k]++;
1773 k++;
1774 continue;
1775 }
1776 vinds[k] = SCM_ARRAY_DIMS (ra)[k].lbnd - 1;
1777 k--;
1778 }
1779 while (k >= 0);
0f2d19dd 1780 return SCM_UNSPECIFIED;
0f2d19dd 1781 }
e42c09cc 1782 }
0f2d19dd 1783}
1bbd0b84 1784#undef FUNC_NAME
0f2d19dd 1785
1cc91f1b 1786
0f2d19dd 1787static int
1bbd0b84 1788raeql_1 (SCM ra0,SCM as_equal,SCM ra1)
0f2d19dd
JB
1789{
1790 SCM e0 = SCM_UNDEFINED, e1 = SCM_UNDEFINED;
1be6b49c
ML
1791 scm_bits_t i0 = 0, i1 = 0;
1792 scm_bits_t inc0 = 1, inc1 = 1;
1793 scm_bits_t n;
0f2d19dd 1794 ra1 = SCM_CAR (ra1);
ff467021 1795 if (SCM_ARRAYP(ra0))
c209c88e
GB
1796 {
1797 n = SCM_ARRAY_DIMS (ra0)->ubnd - SCM_ARRAY_DIMS (ra0)->lbnd + 1;
1798 i0 = SCM_ARRAY_BASE (ra0);
1799 inc0 = SCM_ARRAY_DIMS (ra0)->inc;
1800 ra0 = SCM_ARRAY_V (ra0);
1801 }
e466c6a2
MV
1802 else
1803 n = SCM_INUM (scm_uniform_vector_length (ra0));
ff467021 1804 if (SCM_ARRAYP (ra1))
c209c88e
GB
1805 {
1806 i1 = SCM_ARRAY_BASE (ra1);
1807 inc1 = SCM_ARRAY_DIMS (ra1)->inc;
1808 ra1 = SCM_ARRAY_V (ra1);
1809 }
1810 switch (SCM_TYP7 (ra0))
1811 {
1812 case scm_tc7_vector:
1813 case scm_tc7_wvect:
1814 default:
1815 for (; n--; i0 += inc0, i1 += inc1)
1816 {
1817 if (SCM_FALSEP (as_equal))
1818 {
1819 if (SCM_FALSEP (scm_array_equal_p (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1))))
1820 return 0;
1821 }
1822 else if (SCM_FALSEP (scm_equal_p (RVREF (ra0, i0, e0), RVREF (ra1, i1, e1))))
1823 return 0;
1824 }
1825 return 1;
1826 case scm_tc7_string:
405aaef9
DH
1827 {
1828 char *v0 = SCM_STRING_CHARS (ra0) + i0;
1829 char *v1 = SCM_STRING_CHARS (ra1) + i1;
1830 for (; n--; v0 += inc0, v1 += inc1)
1831 if (*v0 != *v1)
1832 return 0;
1833 return 1;
1834 }
c209c88e 1835 case scm_tc7_byvect:
0f2d19dd 1836 {
405aaef9
DH
1837 char *v0 = ((char *) SCM_UVECTOR_BASE (ra0)) + i0;
1838 char *v1 = ((char *) SCM_UVECTOR_BASE (ra1)) + i1;
c209c88e
GB
1839 for (; n--; v0 += inc0, v1 += inc1)
1840 if (*v0 != *v1)
1841 return 0;
1842 return 1;
0f2d19dd 1843 }
c209c88e
GB
1844 case scm_tc7_bvect:
1845 for (; n--; i0 += inc0, i1 += inc1)
1846 if (SCM_BITVEC_REF (ra0, i0) != SCM_BITVEC_REF (ra1, i1))
1847 return 0;
1848 return 1;
1849 case scm_tc7_uvect:
1850 case scm_tc7_ivect:
0f2d19dd 1851 {
c209c88e
GB
1852 long *v0 = (long *) SCM_VELTS (ra0) + i0;
1853 long *v1 = (long *) SCM_VELTS (ra1) + i1;
1854 for (; n--; v0 += inc0, v1 += inc1)
1855 if (*v0 != *v1)
1856 return 0;
0f2d19dd 1857 return 1;
c209c88e
GB
1858 }
1859 case scm_tc7_svect:
1860 {
1861 short *v0 = (short *) SCM_VELTS (ra0) + i0;
1862 short *v1 = (short *) SCM_VELTS (ra1) + i1;
1863 for (; n--; v0 += inc0, v1 += inc1)
1864 if (*v0 != *v1)
0f2d19dd
JB
1865 return 0;
1866 return 1;
c209c88e 1867 }
5c11cc9d 1868#ifdef HAVE_LONG_LONGS
c209c88e
GB
1869 case scm_tc7_llvect:
1870 {
1871 long long *v0 = (long long *) SCM_VELTS (ra0) + i0;
1872 long long *v1 = (long long *) SCM_VELTS (ra1) + i1;
1873 for (; n--; v0 += inc0, v1 += inc1)
1874 if (*v0 != *v1)
1875 return 0;
1876 return 1;
1877 }
05f92e0f 1878#endif
c209c88e
GB
1879 case scm_tc7_fvect:
1880 {
1881 float *v0 = (float *) SCM_VELTS (ra0) + i0;
1882 float *v1 = (float *) SCM_VELTS (ra1) + i1;
1883 for (; n--; v0 += inc0, v1 += inc1)
1884 if (*v0 != *v1)
1885 return 0;
1886 return 1;
1887 }
c209c88e
GB
1888 case scm_tc7_dvect:
1889 {
1890 double *v0 = (double *) SCM_VELTS (ra0) + i0;
1891 double *v1 = (double *) SCM_VELTS (ra1) + i1;
1892 for (; n--; v0 += inc0, v1 += inc1)
1893 if (*v0 != *v1)
1894 return 0;
1895 return 1;
1896 }
1897 case scm_tc7_cvect:
1898 {
1899 double (*v0)[2] = (double (*)[2]) SCM_VELTS (ra0) + i0;
1900 double (*v1)[2] = (double (*)[2]) SCM_VELTS (ra1) + i1;
1901 for (; n--; v0 += inc0, v1 += inc1)
1902 {
1903 if ((*v0)[0] != (*v1)[0])
0f2d19dd 1904 return 0;
c209c88e
GB
1905 if ((*v0)[1] != (*v1)[1])
1906 return 0;
1907 }
1908 return 1;
0f2d19dd 1909 }
c209c88e 1910 }
0f2d19dd
JB
1911}
1912
1913
1cc91f1b 1914
0f2d19dd 1915static int
1bbd0b84 1916raeql (SCM ra0,SCM as_equal,SCM ra1)
0f2d19dd
JB
1917{
1918 SCM v0 = ra0, v1 = ra1;
1be6b49c
ML
1919 scm_array_dim_t dim0, dim1;
1920 scm_array_dim_t *s0 = &dim0, *s1 = &dim1;
1921 scm_bits_t bas0 = 0, bas1 = 0;
0f2d19dd 1922 int k, unroll = 1, vlen = 1, ndim = 1;
ff467021 1923 if (SCM_ARRAYP (ra0))
c209c88e
GB
1924 {
1925 ndim = SCM_ARRAY_NDIM (ra0);
1926 s0 = SCM_ARRAY_DIMS (ra0);
1927 bas0 = SCM_ARRAY_BASE (ra0);
1928 v0 = SCM_ARRAY_V (ra0);
1929 }
0f2d19dd
JB
1930 else
1931 {
1932 s0->inc = 1;
1933 s0->lbnd = 0;
b226e5f6 1934 s0->ubnd = SCM_INUM (scm_uniform_vector_length (v0)) - 1;
0f2d19dd
JB
1935 unroll = 0;
1936 }
ff467021 1937 if (SCM_ARRAYP (ra1))
c209c88e
GB
1938 {
1939 if (ndim != SCM_ARRAY_NDIM (ra1))
1940 return 0;
1941 s1 = SCM_ARRAY_DIMS (ra1);
1942 bas1 = SCM_ARRAY_BASE (ra1);
1943 v1 = SCM_ARRAY_V (ra1);
1944 }
0f2d19dd
JB
1945 else
1946 {
c209c88e
GB
1947 /*
1948 Huh ? Schizophrenic return type. --hwn
1949 */
0f2d19dd 1950 if (1 != ndim)
c209c88e 1951 return 0;
0f2d19dd
JB
1952 s1->inc = 1;
1953 s1->lbnd = 0;
b226e5f6 1954 s1->ubnd = SCM_INUM (scm_uniform_vector_length (v1)) - 1;
0f2d19dd
JB
1955 unroll = 0;
1956 }
1957 if (SCM_TYP7 (v0) != SCM_TYP7 (v1))
1958 return 0;
1959 for (k = ndim; k--;)
1960 {
1961 if (s0[k].lbnd != s1[k].lbnd || s0[k].ubnd != s1[k].ubnd)
1962 return 0;
1963 if (unroll)
1964 {
1965 unroll = (s0[k].inc == s1[k].inc);
1966 vlen *= s0[k].ubnd - s1[k].lbnd + 1;
1967 }
1968 }
fee7ef83 1969 if (unroll && bas0 == bas1 && SCM_EQ_P (v0, v1))
c209c88e 1970 return 1;
0f2d19dd
JB
1971 return scm_ramapc (raeql_1, as_equal, ra0, scm_cons (ra1, SCM_EOL), "");
1972}
1973
1cc91f1b 1974
0f2d19dd 1975SCM
1bbd0b84 1976scm_raequal (SCM ra0, SCM ra1)
0f2d19dd 1977{
156dcb09 1978 return SCM_BOOL(raeql (ra0, SCM_BOOL_T, ra1));
0f2d19dd
JB
1979}
1980
4079f87e 1981#if 0
c3ee7520
GB
1982/* GJB:FIXME:: Why not use SCM_DEFINE1 for array-equal? */
1983SCM_DEFINE1 (scm_array_equal_p, "array-equal?", scm_tc7_rpsubr,
c209c88e 1984 (SCM ra0, SCM ra1),
1e6808ea
MG
1985 "Return @code{#t} iff all arguments are arrays with the same\n"
1986 "shape, the same type, and have corresponding elements which are\n"
1987 "either @code{equal?} or @code{array-equal?}. This function\n"
1988 "differs from @code{equal?} in that a one dimensional shared\n"
1989 "array may be @var{array-equal?} but not @var{equal?} to a\n"
1990 "vector or uniform vector.")
4079f87e 1991#define FUNC_NAME s_scm_array_equal_p
0f981281
GB
1992{
1993}
4079f87e
GB
1994#undef FUNC_NAME
1995#endif
1996
0f2d19dd
JB
1997static char s_array_equal_p[] = "array-equal?";
1998
1cc91f1b 1999
0f2d19dd 2000SCM
1bbd0b84 2001scm_array_equal_p (SCM ra0, SCM ra1)
0f2d19dd
JB
2002{
2003 if (SCM_IMP (ra0) || SCM_IMP (ra1))
c209c88e 2004 callequal:return scm_equal_p (ra0, ra1);
ff467021 2005 switch (SCM_TYP7(ra0))
c209c88e
GB
2006 {
2007 default:
2008 goto callequal;
2009 case scm_tc7_bvect:
2010 case scm_tc7_string:
2011 case scm_tc7_byvect:
2012 case scm_tc7_uvect:
2013 case scm_tc7_ivect:
2014 case scm_tc7_fvect:
2015 case scm_tc7_dvect:
2016 case scm_tc7_cvect:
2017 case scm_tc7_vector:
2018 case scm_tc7_wvect:
2019 break;
2020 case scm_tc7_smob:
2021 if (!SCM_ARRAYP (ra0))
0f2d19dd 2022 goto callequal;
c209c88e 2023 }
ff467021 2024 switch (SCM_TYP7 (ra1))
c209c88e
GB
2025 {
2026 default:
2027 goto callequal;
2028 case scm_tc7_bvect:
2029 case scm_tc7_string:
2030 case scm_tc7_byvect:
2031 case scm_tc7_uvect:
2032 case scm_tc7_ivect:
2033 case scm_tc7_fvect:
2034 case scm_tc7_dvect:
2035 case scm_tc7_cvect:
2036 case scm_tc7_vector:
2037 case scm_tc7_wvect:
2038 break;
2039 case scm_tc7_smob:
2040 if (!SCM_ARRAYP (ra1))
0f2d19dd 2041 goto callequal;
c209c88e 2042 }
156dcb09 2043 return SCM_BOOL(raeql (ra0, SCM_BOOL_F, ra1));
0f2d19dd
JB
2044}
2045
2046
1cc91f1b 2047static void
1bbd0b84 2048init_raprocs (ra_iproc *subra)
0f2d19dd
JB
2049{
2050 for (; subra->name; subra++)
86d31dfe
MV
2051 {
2052 SCM sym = scm_str2symbol (subra->name);
2053 SCM var =
2054 scm_sym2var (sym, scm_current_module_lookup_closure (), SCM_BOOL_F);
2055 if (var != SCM_BOOL_F)
2056 subra->sproc = SCM_VARIABLE_REF (var);
2057 else
2058 subra->sproc = SCM_BOOL_F;
2059 }
0f2d19dd
JB
2060}
2061
1cc91f1b 2062
0f2d19dd
JB
2063void
2064scm_init_ramap ()
0f2d19dd
JB
2065{
2066 init_raprocs (ra_rpsubrs);
2067 init_raprocs (ra_asubrs);
9a441ddb 2068 scm_c_define_subr (s_array_equal_p, scm_tc7_rpsubr, scm_array_equal_p);
7a7f7c53 2069 scm_smobs[SCM_TC2SMOBNUM (scm_tc16_array)].equalp = scm_raequal;
8dc9439f 2070#ifndef SCM_MAGIC_SNARFER
a0599745 2071#include "libguile/ramap.x"
8dc9439f 2072#endif
1bbd0b84 2073 scm_add_feature (s_scm_array_for_each);
0f2d19dd 2074}
89e00824
ML
2075
2076/*
2077 Local Variables:
2078 c-file-style: "gnu"
2079 End:
2080*/