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