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