1 /* Copyright (C) 1996, 1998, 2000 Free Software Foundation, Inc.
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)
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.
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
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
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.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
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.
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.
40 * If you do not wish that, delete this exception notice. */
42 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
47 Someone should rename this to arraymap.c; that would reflect the
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.
83 static ra_iproc ra_rpsubrs
[] =
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
},
93 static ra_iproc ra_asubrs
[] =
95 {"+", SCM_UNDEFINED
, scm_ra_sum
},
96 {"-", SCM_UNDEFINED
, scm_ra_difference
},
97 {"*", SCM_UNDEFINED
, scm_ra_product
},
98 {"/", SCM_UNDEFINED
, scm_ra_divide
},
104 /* Fast, recycling scm_vector ref */
105 #define RVREF(ra, i, e) (e = scm_cvref(ra, i, e))
107 /* #define RVREF(ra, i, e) (scm_cvref(ra, i, SCM_UNDEFINED)) to turn off */
109 /* IVDEP means "ignore scm_vector dependencies", meaning we guarantee that
110 elements of scm_vector operands are not aliased */
112 #define IVDEP(test, line) if (test) {_Pragma("ivdep"); line} else {line}
114 #define IVDEP(test, line) line
119 /* inds must be a uvect or ivect, no check. */
124 Yes, this is really ugly, but it prevents multiple code
126 #define BINARY_ELTS_CODE(OPERATOR, type) \
127 do { type *v0 = (type*)SCM_VELTS (ra0);\
128 type *v1 = (type*)SCM_VELTS (ra1);\
130 for (; n-- > 0; i0 += inc0, i1 += inc1) \
131 v0[i0] OPERATOR v1[i1];) \
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) \
139 do { type (*v0)[2] = (type (*)[2]) SCM_VELTS (ra0);\
140 type (*v1)[2] = (type (*)[2]) SCM_VELTS (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]; \
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];\
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];\
170 cind (SCM ra
, SCM inds
)
174 long *ve
= (long*) SCM_VELTS (inds
);
175 if (!SCM_ARRAYP (ra
))
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
;
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;
193 scm_ra_matchp (SCM ra0
, SCM ras
)
197 scm_array_dim
*s0
= &dims
;
201 int exact
= 2 /* 4 */ ; /* Don't care about values >2 (yet?) */
202 if (SCM_IMP (ra0
)) return 0;
203 switch (SCM_TYP7 (ra0
))
215 #ifdef HAVE_LONG_LONGS
223 s0
->ubnd
= (long) SCM_LENGTH (ra0
) - 1;
226 if (!SCM_ARRAYP (ra0
))
228 ndim
= SCM_ARRAY_NDIM (ra0
);
229 s0
= SCM_ARRAY_DIMS (ra0
);
230 bas0
= SCM_ARRAY_BASE (ra0
);
233 while (SCM_NIMP (ras
))
251 #ifdef HAVE_LONG_LONGS
268 if ((0 == s0
->lbnd
) && (s0
->ubnd
== SCM_LENGTH (ra1
) - 1))
272 if (s0
->lbnd
< 0 || s0
->ubnd
>= SCM_LENGTH (ra1
))
277 if (!SCM_ARRAYP (ra1
) || ndim
!= SCM_ARRAY_NDIM (ra1
))
279 s1
= SCM_ARRAY_DIMS (ra1
);
280 if (bas0
!= SCM_ARRAY_BASE (ra1
))
282 for (i
= 0; i
< ndim
; i
++)
287 if (s0
[i
].inc
!= s1
[i
].inc
)
290 if (s0
[i
].lbnd
== s1
[i
].lbnd
&& s0
[i
].ubnd
== s1
[i
].ubnd
)
294 if (s0
[i
].lbnd
< s1
[i
].lbnd
|| s0
[i
].ubnd
> s1
[i
].ubnd
)
295 return (s0
[i
].lbnd
<= s0
[i
].ubnd
? 0 : 1);
304 /* array mapper: apply cproc to each dimension of the given arrays?.
305 int (*cproc) (); procedure to call on unrolled arrays?
306 cproc (dest, source list) or
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. */
313 scm_ramapc (int (*cproc
)(), SCM data
, SCM ra0
, SCM lra
, const char *what
)
320 switch (scm_ra_matchp (ra0
, lra
))
324 scm_wta (ra0
, "array shape mismatch", what
);
327 case 4: /* Try unrolling arrays */
328 kmax
= (SCM_ARRAYP (ra0
) ? SCM_ARRAY_NDIM (ra0
) - 1 : 0);
331 vra0
= scm_array_contents (ra0
, SCM_UNDEFINED
);
332 if (SCM_IMP (vra0
)) goto gencase
;
333 if (!SCM_ARRAYP (vra0
))
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
;
345 for (z
= lra
; SCM_NIMP (z
); z
= SCM_CDR (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
))
353 SCM_ARRAY_BASE (vra1
) = 0;
354 SCM_ARRAY_DIMS (vra1
)->inc
= 1;
355 SCM_ARRAY_V (vra1
) = ra1
;
357 else if (!SCM_ARRAY_CONTP (ra1
))
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
);
365 *plvra
= scm_cons (vra1
, SCM_EOL
);
366 plvra
= SCM_CDRLOC (*plvra
);
368 return (SCM_UNBNDP (data
) ? cproc(vra0
, lvra
) : cproc(vra0
, data
, lvra
));
370 gencase
: /* Have to loop over all dimensions. */
371 vra0
= scm_make_ra (1);
372 if (SCM_ARRAYP (ra0
))
374 kmax
= SCM_ARRAY_NDIM (ra0
) - 1;
377 SCM_ARRAY_DIMS (vra0
)->lbnd
= 0;
378 SCM_ARRAY_DIMS (vra0
)->ubnd
= 0;
379 SCM_ARRAY_DIMS (vra0
)->inc
= 1;
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
;
387 SCM_ARRAY_BASE (vra0
) = SCM_ARRAY_BASE (ra0
);
388 SCM_ARRAY_V (vra0
) = SCM_ARRAY_V (ra0
);
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
;
402 for (z
= lra
; SCM_NIMP (z
); z
= SCM_CDR (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
))
411 SCM_ARRAY_DIMS (vra1
)->inc
= SCM_ARRAY_DIMS (ra1
)[kmax
].inc
;
412 SCM_ARRAY_V (vra1
) = SCM_ARRAY_V (ra1
);
416 SCM_ARRAY_DIMS (vra1
)->inc
= 1;
417 SCM_ARRAY_V (vra1
) = ra1
;
419 *plvra
= scm_cons (vra1
, SCM_EOL
);
420 plvra
= SCM_CDRLOC (*plvra
);
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
;
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
)))
440 if (vinds
[k
] < SCM_ARRAY_DIMS (ra0
)[k
].ubnd
)
446 vinds
[k
] = SCM_ARRAY_DIMS (ra0
)[k
].lbnd
- 1;
455 SCM_DEFINE (scm_array_fill_x
, "array-fill!", 2, 0, 0,
457 "Stores @var{fill} in every element of @var{array}. The value returned\n"
459 #define FUNC_NAME s_scm_array_fill_x
461 scm_ramapc (scm_array_fill_int
, fill
, ra
, SCM_EOL
, FUNC_NAME
);
462 return SCM_UNSPECIFIED
;
466 /* to be used as cproc in scm_ramapc to fill an array dimension with
469 scm_array_fill_int (SCM ra
, SCM fill
, SCM ignore
)
470 #define FUNC_NAME s_scm_array_fill_x
473 scm_sizet n
= SCM_ARRAY_DIMS (ra
)->ubnd
- SCM_ARRAY_DIMS (ra
)->lbnd
+ 1;
474 long inc
= SCM_ARRAY_DIMS (ra
)->inc
;
475 scm_sizet base
= SCM_ARRAY_BASE (ra
);
477 ra
= SCM_ARRAY_V (ra
);
481 for (i
= base
; n
--; i
+= inc
)
482 scm_array_set_x (ra
, fill
, SCM_MAKINUM (i
));
486 for (i
= base
; n
--; i
+= inc
)
487 SCM_VELTS (ra
)[i
] = fill
;
490 SCM_ASRTGO (SCM_CHARP (fill
), badarg2
);
491 for (i
= base
; n
--; i
+= inc
)
492 SCM_CHARS (ra
)[i
] = SCM_CHAR (fill
);
495 if (SCM_CHARP (fill
))
496 fill
= SCM_MAKINUM ((char) SCM_CHAR (fill
));
497 SCM_ASRTGO (SCM_INUMP (fill
)
498 && -128 <= SCM_INUM (fill
) && SCM_INUM (fill
) < 128,
500 for (i
= base
; n
--; i
+= inc
)
501 SCM_CHARS (ra
)[i
] = SCM_INUM (fill
);
505 long *ve
= (long *) SCM_VELTS (ra
);
506 if (1 == inc
&& (n
>= SCM_LONG_BIT
|| n
== SCM_LENGTH (ra
)))
508 i
= base
/ SCM_LONG_BIT
;
509 if (SCM_BOOL_F
== fill
)
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
++)
515 if ((base
+ n
) % SCM_LONG_BIT
) /* trailing partial word */
516 ve
[i
] &= (~0L << ((base
+ n
) % SCM_LONG_BIT
));
518 else if (SCM_BOOL_T
== fill
)
520 if (base
% SCM_LONG_BIT
)
521 ve
[i
++] |= ~0L << (base
% SCM_LONG_BIT
);
522 for (; i
< (base
+ n
) / SCM_LONG_BIT
; i
++)
524 if ((base
+ n
) % SCM_LONG_BIT
)
525 ve
[i
] |= ~(~0L << ((base
+ n
) % SCM_LONG_BIT
));
528 badarg2
:SCM_WTA (2,fill
);
532 if (SCM_BOOL_F
== fill
)
533 for (i
= base
; n
--; i
+= inc
)
534 ve
[i
/ SCM_LONG_BIT
] &= ~(1L << (i
% SCM_LONG_BIT
));
535 else if (SCM_BOOL_T
== fill
)
536 for (i
= base
; n
--; i
+= inc
)
537 ve
[i
/ SCM_LONG_BIT
] |= (1L << (i
% SCM_LONG_BIT
));
545 unsigned long f
= SCM_NUM2ULONG (2,fill
);
546 unsigned long *ve
= (long *) SCM_VELTS (ra
);
548 for (i
= base
; n
--; i
+= inc
)
554 long f
= SCM_NUM2LONG (2,fill
);
555 long *ve
= (long *) SCM_VELTS (ra
);
557 for (i
= base
; n
--; i
+= inc
)
562 SCM_ASRTGO (SCM_INUMP (fill
), badarg2
);
564 short f
= SCM_INUM (fill
);
565 short *ve
= (short *) SCM_VELTS (ra
);
567 if (f
!= SCM_INUM (fill
))
568 SCM_OUT_OF_RANGE (2, fill
);
569 for (i
= base
; n
--; i
+= inc
)
573 #ifdef HAVE_LONG_LONGS
576 long long f
= SCM_NUM2LONG_LONG (2,fill
);
577 long long *ve
= (long long *) SCM_VELTS (ra
);
579 for (i
= base
; n
--; i
+= inc
)
586 float f
, *ve
= (float *) SCM_VELTS (ra
);
587 SCM_ASRTGO (SCM_REALP (fill
), badarg2
);
588 f
= SCM_REALPART (fill
);
589 for (i
= base
; n
--; i
+= inc
)
595 double f
, *ve
= (double *) SCM_VELTS (ra
);
596 SCM_ASRTGO (SCM_REALP (fill
), badarg2
);
597 f
= SCM_REALPART (fill
);
598 for (i
= base
; n
--; i
+= inc
)
605 double (*ve
)[2] = (double (*)[2]) SCM_VELTS (ra
);
606 SCM_ASRTGO (SCM_INEXP (fill
), badarg2
);
607 fr
= SCM_REALPART (fill
);
608 fi
= (SCM_CPLXP (fill
) ? SCM_IMAG (fill
) : 0.0);
609 for (i
= base
; n
--; i
+= inc
)
624 racp (SCM src
, SCM dst
)
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
);
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
);
636 /* untested optimization: don't copy if we're we. This allows the
637 ugly UNICOS macros (IVDEP) to go .
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
));
656 if (scm_tc7_string
!= SCM_TYP7 (dst
))
658 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
659 SCM_CHARS (dst
)[i_d
] = SCM_CHARS (src
)[i_s
];
662 if (scm_tc7_bvect
!= SCM_TYP7 (dst
))
664 if (1 == inc_d
&& 1 == inc_s
&& i_s
% SCM_LONG_BIT
== i_d
% SCM_LONG_BIT
&& n
>= SCM_LONG_BIT
)
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
)));
675 n
-= SCM_LONG_BIT
- (i_s
% SCM_LONG_BIT
);
677 for (; n
>= SCM_LONG_BIT
; n
-= SCM_LONG_BIT
, sv
++, dv
++)
679 if (n
) /* trailing partial word */
680 *dv
= (*dv
& (~0L << n
)) | (*sv
& ~(~0L << n
));
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
);
688 SCM_BITVEC_CLR(dst
, i_d
);
692 if (scm_tc7_uvect
!= SCM_TYP7 (src
))
696 long *d
= (long *) SCM_VELTS (dst
), *s
= (long *) SCM_VELTS (src
);
697 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
702 if (scm_tc7_uvect
!= SCM_TYP7 (src
) && scm_tc7_ivect
!= SCM_TYP7 (src
))
706 long *d
= (long *) SCM_VELTS (dst
), *s
= (long *) SCM_VELTS (src
);
707 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
713 float *d
= (float *) SCM_VELTS (dst
);
714 float *s
= (float *) SCM_VELTS (src
);
722 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
723 d
[i_d
] = ((long *) s
)[i_s
];
726 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
730 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
731 d
[i_d
] = ((double *) s
)[i_s
];
738 double *d
= (double *) SCM_VELTS (dst
);
739 double *s
= (double *) SCM_VELTS (src
);
747 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
748 d
[i_d
] = ((long *) s
)[i_s
];
751 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
752 d
[i_d
] = ((float *) s
)[i_s
];
755 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
763 double (*d
)[2] = (double (*)[2]) SCM_VELTS (dst
);
764 double (*s
)[2] = (double (*)[2]) SCM_VELTS (src
);
772 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
774 d
[i_d
][0] = ((long *) s
)[i_s
];
779 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
781 d
[i_d
][0] = ((float *) s
)[i_s
];
786 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
788 d
[i_d
][0] = ((double *) s
)[i_s
];
793 for (; n
-- > 0; i_s
+= inc_s
, i_d
+= inc_d
)
795 d
[i_d
][0] = s
[i_s
][0];
796 d
[i_d
][1] = s
[i_s
][1];
806 /* This name is obsolete. Will go away in release 1.5. */
807 SCM_REGISTER_PROC(s_serial_array_copy_x
, "serial-array-copy!", 2, 0, 0, scm_array_copy_x
);
808 SCM_REGISTER_PROC(s_array_copy_in_order_x
, "array-copy-in-order!", 2, 0, 0, scm_array_copy_x
);
811 SCM_DEFINE (scm_array_copy_x
, "array-copy!", 2, 0, 0,
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.")
817 #define FUNC_NAME s_scm_array_copy_x
819 scm_ramapc (racp
, SCM_UNDEFINED
, src
, scm_cons (dst
, SCM_EOL
), FUNC_NAME
);
820 return SCM_UNSPECIFIED
;
824 /* Functions callable by ARRAY-MAP! */
828 scm_ra_eqp (SCM ra0
, SCM ras
)
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)
843 SCM e1
= SCM_UNDEFINED
, e2
= SCM_UNDEFINED
;
844 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
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
);
852 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
853 if (SCM_BITVEC_REF (ra0
, i0
))
854 if (SCM_VELTS (ra1
)[i1
] != SCM_VELTS (ra2
)[i2
])
855 SCM_BITVEC_CLR (ra0
, i0
);
858 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
859 if (SCM_BITVEC_REF (ra0
, i0
))
860 if (((float *) SCM_VELTS (ra1
))[i1
] != ((float *) SCM_VELTS (ra2
))[i2
])
861 SCM_BITVEC_CLR (ra0
, i0
);
864 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
865 if (SCM_BITVEC_REF (ra0
, i0
))
866 if (((double *) SCM_VELTS (ra1
))[i1
] != ((double *) SCM_VELTS (ra2
))[i2
])
867 SCM_BITVEC_CLR (ra0
, i0
);
870 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
871 if (SCM_BITVEC_REF (ra0
, i0
))
872 if (((double *) SCM_VELTS (ra1
))[2 * i1
] != ((double *) SCM_VELTS (ra2
))[2 * i2
] ||
873 ((double *) SCM_VELTS (ra1
))[2 * i1
+ 1] != ((double *) SCM_VELTS (ra2
))[2 * i2
+ 1])
874 SCM_BITVEC_CLR (ra0
, i0
);
880 /* opt 0 means <, nonzero means >= */
883 ra_compare (SCM ra0
,SCM ra1
,SCM ra2
,int opt
)
885 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra0
)->lbnd
+ 1;
886 scm_sizet i0
= SCM_ARRAY_BASE (ra0
), i1
= SCM_ARRAY_BASE (ra1
), i2
= SCM_ARRAY_BASE (ra2
);
887 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
;
888 long inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
889 long inc2
= SCM_ARRAY_DIMS (ra1
)->inc
;
890 ra0
= SCM_ARRAY_V (ra0
);
891 ra1
= SCM_ARRAY_V (ra1
);
892 ra2
= SCM_ARRAY_V (ra2
);
893 switch (SCM_TYP7 (ra1
) == SCM_TYP7 (ra2
) ? SCM_TYP7 (ra1
) : 0)
897 SCM e1
= SCM_UNDEFINED
, e2
= SCM_UNDEFINED
;
898 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
899 if (SCM_BITVEC_REF (ra0
, i0
))
901 SCM_NFALSEP (scm_less_p (RVREF (ra1
, i1
, e1
), RVREF (ra2
, i2
, e2
))) :
902 SCM_FALSEP (scm_less_p (RVREF (ra1
, i1
, e1
), RVREF (ra2
, i2
, e2
))))
903 SCM_BITVEC_CLR (ra0
, i0
);
908 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
910 if (SCM_BITVEC_REF (ra0
, i0
))
912 SCM_VELTS (ra1
)[i1
] < SCM_VELTS (ra2
)[i2
] :
913 SCM_VELTS (ra1
)[i1
] >= SCM_VELTS (ra2
)[i2
])
914 SCM_BITVEC_CLR (ra0
, i0
);
918 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
919 if (SCM_BITVEC_REF(ra0
, i0
))
921 ((float *) SCM_VELTS (ra1
))[i1
] < ((float *) SCM_VELTS (ra2
))[i2
] :
922 ((float *) SCM_VELTS (ra1
))[i1
] >= ((float *) SCM_VELTS (ra2
))[i2
])
923 SCM_BITVEC_CLR (ra0
, i0
);
926 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
927 if (SCM_BITVEC_REF (ra0
, i0
))
929 ((double *) SCM_VELTS (ra1
))[i1
] < ((double *) SCM_VELTS (ra2
))[i2
] :
930 ((double *) SCM_VELTS (ra1
))[i1
] >= ((double *) SCM_VELTS (ra2
))[i2
])
931 SCM_BITVEC_CLR (ra0
, i0
);
940 scm_ra_lessp (SCM ra0
, SCM ras
)
942 return ra_compare (ra0
, SCM_CAR (ras
), SCM_CAR (SCM_CDR (ras
)), 0);
947 scm_ra_leqp (SCM ra0
, SCM ras
)
949 return ra_compare (ra0
, SCM_CAR (SCM_CDR (ras
)), SCM_CAR (ras
), 1);
954 scm_ra_grp (SCM ra0
, SCM ras
)
956 return ra_compare (ra0
, SCM_CAR (SCM_CDR (ras
)), SCM_CAR (ras
), 0);
961 scm_ra_greqp (SCM ra0
, SCM ras
)
963 return ra_compare (ra0
, SCM_CAR (ras
), SCM_CAR (SCM_CDR (ras
)), 1);
968 scm_ra_sum (SCM ra0
, SCM ras
)
970 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra0
)->lbnd
+ 1;
971 scm_sizet i0
= SCM_ARRAY_BASE (ra0
);
972 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
;
973 ra0
= SCM_ARRAY_V (ra0
);
976 SCM ra1
= SCM_CAR (ras
);
977 scm_sizet i1
= SCM_ARRAY_BASE (ra1
);
978 long inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
979 ra1
= SCM_ARRAY_V (ra1
);
980 switch (SCM_TYP7 (ra0
) == SCM_TYP7 (ra1
) ? SCM_TYP7 (ra0
) : 0)
984 SCM e0
= SCM_UNDEFINED
, e1
= SCM_UNDEFINED
;
985 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
986 scm_array_set_x (ra0
, scm_sum (RVREF (ra0
, i0
, e0
), RVREF (ra1
, i1
, e1
)),
992 BINARY_ELTS_CODE( +=, long);
994 BINARY_ELTS_CODE( +=, float);
996 BINARY_ELTS_CODE( +=, double);
998 BINARY_PAIR_ELTS_CODE( +=, double);
1007 scm_ra_difference (SCM ra0
, SCM ras
)
1009 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra0
)->lbnd
+ 1;
1010 scm_sizet i0
= SCM_ARRAY_BASE (ra0
);
1011 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
;
1012 ra0
= SCM_ARRAY_V (ra0
);
1013 if (SCM_NULLP (ras
))
1015 switch (SCM_TYP7 (ra0
))
1019 SCM e0
= SCM_UNDEFINED
;
1020 for (; n
-- > 0; i0
+= inc0
)
1021 scm_array_set_x (ra0
,
1022 scm_difference (RVREF (ra0
, i0
, e0
), SCM_UNDEFINED
),
1027 UNARY_ELTS_CODE( = -, float);
1029 UNARY_ELTS_CODE( = -, double);
1031 UNARY_PAIR_ELTS_CODE( = -, double);
1036 SCM ra1
= SCM_CAR (ras
);
1037 scm_sizet i1
= SCM_ARRAY_BASE (ra1
);
1038 long inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1039 ra1
= SCM_ARRAY_V (ra1
);
1040 switch (SCM_TYP7 (ra0
) == SCM_TYP7 (ra1
) ? SCM_TYP7 (ra0
) : 0)
1044 SCM e0
= SCM_UNDEFINED
, e1
= SCM_UNDEFINED
;
1045 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1046 scm_array_set_x (ra0
, scm_difference (RVREF (ra0
, i0
, e0
), RVREF (ra1
, i1
, e1
)), SCM_MAKINUM (i0
));
1050 BINARY_ELTS_CODE( -=, float);
1052 BINARY_ELTS_CODE( -=, double);
1054 BINARY_PAIR_ELTS_CODE( -=, double);
1063 scm_ra_product (SCM ra0
, SCM ras
)
1065 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra0
)->lbnd
+ 1;
1066 scm_sizet i0
= SCM_ARRAY_BASE (ra0
);
1067 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
;
1068 ra0
= SCM_ARRAY_V (ra0
);
1069 if (SCM_NNULLP (ras
))
1071 SCM ra1
= SCM_CAR (ras
);
1072 scm_sizet i1
= SCM_ARRAY_BASE (ra1
);
1073 long inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1074 ra1
= SCM_ARRAY_V (ra1
);
1075 switch (SCM_TYP7 (ra0
) == SCM_TYP7 (ra1
) ? SCM_TYP7 (ra0
) : 0)
1079 SCM e0
= SCM_UNDEFINED
, e1
= SCM_UNDEFINED
;
1080 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1081 scm_array_set_x (ra0
, scm_product (RVREF (ra0
, i0
, e0
), RVREF (ra1
, i1
, e1
)),
1087 BINARY_ELTS_CODE( *=, long);
1089 BINARY_ELTS_CODE( *=, float);
1091 BINARY_ELTS_CODE( *=, double);
1094 double (*v0
)[2] = (double (*)[2]) SCM_VELTS (ra0
);
1096 double (*v1
)[2] = (double (*)[2]) SCM_VELTS (ra1
);
1098 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1100 r
= v0
[i0
][0] * v1
[i1
][0] - v0
[i0
][1] * v1
[i1
][1];
1101 v0
[i0
][1] = v0
[i0
][0] * v1
[i1
][1] + v0
[i0
][1] * v1
[i1
][0];
1114 scm_ra_divide (SCM ra0
, SCM ras
)
1116 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra0
)->lbnd
+ 1;
1117 scm_sizet i0
= SCM_ARRAY_BASE (ra0
);
1118 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
;
1119 ra0
= SCM_ARRAY_V (ra0
);
1120 if (SCM_NULLP (ras
))
1122 switch (SCM_TYP7 (ra0
))
1126 SCM e0
= SCM_UNDEFINED
;
1127 for (; n
-- > 0; i0
+= inc0
)
1128 scm_array_set_x (ra0
, scm_divide (RVREF (ra0
, i0
, e0
), SCM_UNDEFINED
), SCM_MAKINUM (i0
));
1132 UNARY_ELTS_CODE( = 1.0 / , float);
1134 UNARY_ELTS_CODE( = 1.0 / , double);
1138 double (*v0
)[2] = (double (*)[2]) SCM_VELTS (ra0
);
1139 for (; n
-- > 0; i0
+= inc0
)
1141 d
= v0
[i0
][0] * v0
[i0
][0] + v0
[i0
][1] * v0
[i0
][1];
1151 SCM ra1
= SCM_CAR (ras
);
1152 scm_sizet i1
= SCM_ARRAY_BASE (ra1
);
1153 long inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1154 ra1
= SCM_ARRAY_V (ra1
);
1155 switch (SCM_TYP7 (ra0
) == SCM_TYP7 (ra1
) ? SCM_TYP7 (ra0
) : 0)
1159 SCM e0
= SCM_UNDEFINED
, e1
= SCM_UNDEFINED
;
1160 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1161 scm_array_set_x (ra0
, scm_divide (RVREF (ra0
, i0
, e0
), RVREF (ra1
, i1
, e1
)), SCM_MAKINUM (i0
));
1165 BINARY_ELTS_CODE( /=, float);
1167 BINARY_ELTS_CODE( /=, double);
1170 register double d
, r
;
1171 double (*v0
)[2] = (double (*)[2]) SCM_VELTS (ra0
);
1172 double (*v1
)[2] = (double (*)[2]) SCM_VELTS (ra1
);
1174 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1176 d
= v1
[i1
][0] * v1
[i1
][0] + v1
[i1
][1] * v1
[i1
][1];
1177 r
= (v0
[i0
][0] * v1
[i1
][0] + v0
[i0
][1] * v1
[i1
][1]) / d
;
1178 v0
[i0
][1] = (v0
[i0
][1] * v1
[i1
][0] - v0
[i0
][0] * v1
[i1
][1]) / d
;
1191 scm_array_identity (SCM dst
, SCM src
)
1193 return racp (SCM_CAR (src
), scm_cons (dst
, SCM_EOL
));
1199 ramap (SCM ra0
,SCM proc
,SCM ras
)
1201 long i
= SCM_ARRAY_DIMS (ra0
)->lbnd
;
1202 long inc
= SCM_ARRAY_DIMS (ra0
)->inc
;
1203 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
;
1204 long base
= SCM_ARRAY_BASE (ra0
) - i
* inc
;
1205 ra0
= SCM_ARRAY_V (ra0
);
1206 if (SCM_NULLP (ras
))
1208 scm_array_set_x (ra0
, scm_apply (proc
, SCM_EOL
, SCM_EOL
), SCM_MAKINUM (i
* inc
+ base
));
1211 SCM ra1
= SCM_CAR (ras
);
1212 SCM args
, *ve
= &ras
;
1213 scm_sizet k
, i1
= SCM_ARRAY_BASE (ra1
);
1214 long inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1215 ra1
= SCM_ARRAY_V (ra1
);
1216 ras
= SCM_CDR (ras
);
1221 ras
= scm_vector (ras
);
1222 ve
= SCM_VELTS (ras
);
1224 for (; i
<= n
; i
++, i1
+= inc1
)
1227 for (k
= SCM_LENGTH (ras
); k
--;)
1228 args
= scm_cons (scm_uniform_vector_ref (ve
[k
], SCM_MAKINUM (i
)), args
);
1229 args
= scm_cons (scm_cvref (ra1
, i1
, SCM_UNDEFINED
), args
);
1230 scm_array_set_x (ra0
, scm_apply (proc
, args
, SCM_EOL
), SCM_MAKINUM (i
* inc
+ base
));
1238 ramap_cxr (SCM ra0
,SCM proc
,SCM ras
)
1240 SCM ra1
= SCM_CAR (ras
);
1241 SCM e1
= SCM_UNDEFINED
;
1242 scm_sizet i0
= SCM_ARRAY_BASE (ra0
), i1
= SCM_ARRAY_BASE (ra1
);
1243 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
, inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1244 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra1
)->lbnd
+ 1;
1245 ra0
= SCM_ARRAY_V (ra0
);
1246 ra1
= SCM_ARRAY_V (ra1
);
1247 switch (SCM_TYP7 (ra0
))
1251 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1252 scm_array_set_x (ra0
, scm_apply (proc
, RVREF (ra1
, i1
, e1
), scm_listofnull
), SCM_MAKINUM (i0
));
1256 float *dst
= (float *) SCM_VELTS (ra0
);
1257 switch (SCM_TYP7 (ra1
))
1262 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1263 dst
[i0
] = SCM_DSUBRF (proc
) ((double) ((float *) SCM_VELTS (ra1
))[i1
]);
1267 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1268 dst
[i0
] = SCM_DSUBRF (proc
) (SCM_UNPACK (SCM_VELTS (ra1
)[i1
]));
1275 double *dst
= (double *) SCM_VELTS (ra0
);
1276 switch (SCM_TYP7 (ra1
))
1281 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1282 dst
[i0
] = SCM_DSUBRF (proc
) (((double *) SCM_VELTS (ra1
))[i1
]);
1286 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1287 dst
[i0
] = SCM_DSUBRF (proc
) (SCM_UNPACK (SCM_VELTS (ra1
)[i1
]));
1299 ramap_rp (SCM ra0
,SCM proc
,SCM ras
)
1301 SCM ra1
= SCM_CAR (ras
), ra2
= SCM_CAR (SCM_CDR (ras
));
1302 SCM e1
= SCM_UNDEFINED
, e2
= SCM_UNDEFINED
;
1303 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra0
)->lbnd
+ 1;
1304 scm_sizet i0
= SCM_ARRAY_BASE (ra0
), i1
= SCM_ARRAY_BASE (ra1
), i2
= SCM_ARRAY_BASE (ra2
);
1305 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
;
1306 long inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1307 long inc2
= SCM_ARRAY_DIMS (ra1
)->inc
;
1308 ra0
= SCM_ARRAY_V (ra0
);
1309 ra1
= SCM_ARRAY_V (ra1
);
1310 ra2
= SCM_ARRAY_V (ra2
);
1311 switch (SCM_TYP7 (ra1
) == SCM_TYP7 (ra2
) ? SCM_TYP7 (ra1
) : 0)
1314 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
1315 if (SCM_BITVEC_REF (ra0
, i0
))
1316 if (SCM_FALSEP (SCM_SUBRF (proc
) (RVREF (ra1
, i1
, e1
), RVREF (ra2
, i2
, e2
))))
1317 SCM_BITVEC_CLR (ra0
, i0
);
1321 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
1322 if (SCM_BITVEC_REF (ra0
, i0
))
1324 /* DIRK:FIXME:: There should be a way to access the elements
1325 of a cell as raw data. Further: How can we be sure that
1326 the values fit into an inum?
1328 SCM n1
= SCM_MAKINUM (((long *) SCM2PTR (SCM_CDR (ra1
)))[i1
]);
1329 SCM n2
= SCM_MAKINUM (((long *) SCM2PTR (SCM_CDR (ra2
)))[i2
]);
1330 if (SCM_FALSEP (SCM_SUBRF (proc
) (n1
, n2
)));
1331 SCM_BITVEC_CLR (ra0
, i0
);
1336 SCM a1
= scm_make_real (1.0), a2
= scm_make_real (1.0);
1337 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
1338 if (SCM_BITVEC_REF (ra0
, i0
))
1340 SCM_REAL_VALUE (a1
) = ((float *) SCM_VELTS (ra1
))[i1
];
1341 SCM_REAL_VALUE (a2
) = ((float *) SCM_VELTS (ra2
))[i2
];
1342 if (SCM_FALSEP (SCM_SUBRF (proc
) (a1
, a2
)))
1343 SCM_BITVEC_CLR (ra0
, i0
);
1349 SCM a1
= scm_makdbl (1.0 / 3.0, 0.0), a2
= scm_makdbl (1.0 / 3.0, 0.0);
1350 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
1351 if (SCM_BITVEC_REF (ra0
, i0
))
1353 SCM_REAL (a1
) = ((double *) SCM_VELTS (ra1
))[i1
];
1354 SCM_REAL (a2
) = ((double *) SCM_VELTS (ra2
))[i2
];
1355 if (SCM_FALSEP (SCM_SUBRF (proc
) (a1
, a2
)))
1356 SCM_BITVEC_CLR (ra0
, i0
);
1362 SCM a1
= scm_makdbl (1.0, 1.0), a2
= scm_makdbl (1.0, 1.0);
1363 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
1364 if (SCM_BITVEC_REF (ra0
, i0
))
1366 SCM_COMPLEX_REAL (a1
) = ((double *) SCM_VELTS (ra1
))[2 * i1
];
1367 SCM_COMPLEX_IMAG (a1
) = ((double *) SCM_VELTS (ra1
))[2 * i1
+ 1];
1368 SCM_COMPLEX_REAL (a2
) = ((double *) SCM_VELTS (ra2
))[2 * i2
];
1369 SCM_COMPLEX_IMAG (a2
) = ((double *) SCM_VELTS (ra2
))[2 * i2
+ 1];
1370 if (SCM_FALSEP (SCM_SUBRF (proc
) (a1
, a2
)))
1371 SCM_BITVEC_CLR (ra0
, i0
);
1382 ramap_1 (SCM ra0
,SCM proc
,SCM ras
)
1384 SCM ra1
= SCM_CAR (ras
);
1385 SCM e1
= SCM_UNDEFINED
;
1386 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra0
)->lbnd
+ 1;
1387 scm_sizet i0
= SCM_ARRAY_BASE (ra0
), i1
= SCM_ARRAY_BASE (ra1
);
1388 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
, inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1389 ra0
= SCM_ARRAY_V (ra0
);
1390 ra1
= SCM_ARRAY_V (ra1
);
1391 if (scm_tc7_vector
== SCM_TYP7 (ra0
) || scm_tc7_wvect
== SCM_TYP7 (ra0
))
1392 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1393 scm_array_set_x (ra0
, SCM_SUBRF (proc
) (scm_cvref (ra1
, i1
, SCM_UNDEFINED
)), SCM_MAKINUM (i0
));
1395 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1396 scm_array_set_x (ra0
, SCM_SUBRF (proc
) (RVREF (ra1
, i1
, e1
)), SCM_MAKINUM (i0
));
1403 ramap_2o (SCM ra0
,SCM proc
,SCM ras
)
1405 SCM ra1
= SCM_CAR (ras
);
1406 SCM e1
= SCM_UNDEFINED
;
1407 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra0
)->lbnd
+ 1;
1408 scm_sizet i0
= SCM_ARRAY_BASE (ra0
), i1
= SCM_ARRAY_BASE (ra1
);
1409 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
, inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1410 ra0
= SCM_ARRAY_V (ra0
);
1411 ra1
= SCM_ARRAY_V (ra1
);
1412 ras
= SCM_CDR (ras
);
1413 if (SCM_NULLP (ras
))
1415 if (scm_tc7_vector
== SCM_TYP7 (ra0
)
1416 || scm_tc7_wvect
== SCM_TYP7 (ra0
))
1418 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1419 scm_array_set_x (ra0
, SCM_SUBRF (proc
) (scm_cvref (ra1
, i1
, SCM_UNDEFINED
), SCM_UNDEFINED
),
1422 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1423 scm_array_set_x (ra0
, SCM_SUBRF (proc
) (RVREF (ra1
, i1
, e1
), SCM_UNDEFINED
),
1428 SCM ra2
= SCM_CAR (ras
);
1429 SCM e2
= SCM_UNDEFINED
;
1430 scm_sizet i2
= SCM_ARRAY_BASE (ra2
);
1431 long inc2
= SCM_ARRAY_DIMS (ra2
)->inc
;
1432 ra2
= SCM_ARRAY_V (ra2
);
1433 if (scm_tc7_vector
== SCM_TYP7 (ra0
) || scm_tc7_wvect
== SCM_TYP7 (ra0
))
1434 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
1435 scm_array_set_x (ra0
,
1436 SCM_SUBRF (proc
) (scm_cvref (ra1
, i1
, SCM_UNDEFINED
), scm_cvref (ra2
, i2
, SCM_UNDEFINED
)),
1439 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
, i2
+= inc2
)
1440 scm_array_set_x (ra0
,
1441 SCM_SUBRF (proc
) (RVREF (ra1
, i1
, e1
), RVREF (ra2
, i2
, e2
)),
1450 ramap_a (SCM ra0
,SCM proc
,SCM ras
)
1452 SCM e0
= SCM_UNDEFINED
, e1
= SCM_UNDEFINED
;
1453 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra0
)->lbnd
+ 1;
1454 scm_sizet i0
= SCM_ARRAY_BASE (ra0
);
1455 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
;
1456 ra0
= SCM_ARRAY_V (ra0
);
1457 if (SCM_NULLP (ras
))
1458 for (; n
-- > 0; i0
+= inc0
)
1459 scm_array_set_x (ra0
, SCM_SUBRF (proc
) (RVREF (ra0
, i0
, e0
), SCM_UNDEFINED
), SCM_MAKINUM (i0
));
1462 SCM ra1
= SCM_CAR (ras
);
1463 scm_sizet i1
= SCM_ARRAY_BASE (ra1
);
1464 long inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1465 ra1
= SCM_ARRAY_V (ra1
);
1466 for (; n
-- > 0; i0
+= inc0
, i1
+= inc1
)
1467 scm_array_set_x (ra0
, SCM_SUBRF (proc
) (RVREF (ra0
, i0
, e0
), RVREF (ra1
, i1
, e1
)),
1473 /* This name is obsolete. Will go away in release 1.5. */
1474 SCM_REGISTER_PROC(s_serial_array_map_x
, "serial-array-map!", 2, 0, 1, scm_array_map_x
);
1475 SCM_REGISTER_PROC(s_array_map_in_order_x
, "array-map-in-order!", 2, 0, 1, scm_array_map_x
);
1478 SCM_DEFINE (scm_array_map_x
, "array-map!", 2, 0, 1,
1479 (SCM ra0
, SCM proc
, SCM lra
),
1480 "@var{array1}, @dots{} must have the same number of dimensions as\n"
1481 "@var{array0} and have a range for each index which includes the range\n"
1482 "for the corresponding index in @var{array0}. @var{proc} is applied to\n"
1483 "each tuple of elements of @var{array1} @dots{} and the result is stored\n"
1484 "as the corresponding element in @var{array0}. The value returned is\n"
1485 "unspecified. The order of application is unspecified.")
1486 #define FUNC_NAME s_scm_array_map_x
1488 SCM_VALIDATE_PROC (2,proc
);
1489 switch (SCM_TYP7 (proc
))
1493 scm_ramapc (ramap
, proc
, ra0
, lra
, FUNC_NAME
);
1494 return SCM_UNSPECIFIED
;
1495 case scm_tc7_subr_1
:
1496 scm_ramapc (ramap_1
, proc
, ra0
, lra
, FUNC_NAME
);
1497 return SCM_UNSPECIFIED
;
1498 case scm_tc7_subr_2
:
1499 case scm_tc7_subr_2o
:
1500 scm_ramapc (ramap_2o
, proc
, ra0
, lra
, FUNC_NAME
);
1501 return SCM_UNSPECIFIED
;
1503 if (!SCM_SUBRF (proc
))
1505 scm_ramapc (ramap_cxr
, proc
, ra0
, lra
, FUNC_NAME
);
1506 return SCM_UNSPECIFIED
;
1507 case scm_tc7_rpsubr
:
1510 if (SCM_FALSEP (scm_array_p (ra0
, SCM_BOOL_T
)))
1512 scm_array_fill_x (ra0
, SCM_BOOL_T
);
1513 for (p
= ra_rpsubrs
; p
->name
; p
++)
1514 if (proc
== p
->sproc
)
1516 while (SCM_NNULLP (lra
) && SCM_NNULLP (SCM_CDR (lra
)))
1518 scm_ramapc (p
->vproc
, SCM_UNDEFINED
, ra0
, lra
, FUNC_NAME
);
1519 lra
= SCM_CDR (lra
);
1521 return SCM_UNSPECIFIED
;
1523 while (SCM_NNULLP (lra
) && SCM_NNULLP (SCM_CDR (lra
)))
1525 scm_ramapc (ramap_rp
, proc
, ra0
, lra
, FUNC_NAME
);
1526 lra
= SCM_CDR (lra
);
1528 return SCM_UNSPECIFIED
;
1531 if (SCM_NULLP (lra
))
1533 SCM prot
, fill
= SCM_SUBRF (proc
) (SCM_UNDEFINED
, SCM_UNDEFINED
);
1534 if (SCM_INUMP(fill
))
1536 prot
= scm_array_prototype (ra0
);
1537 if (SCM_INEXP (prot
))
1538 fill
= scm_makdbl ((double) SCM_INUM (fill
), 0.0);
1541 scm_array_fill_x (ra0
, fill
);
1545 SCM tail
, ra1
= SCM_CAR (lra
);
1546 SCM v0
= (SCM_ARRAYP (ra0
) ? SCM_ARRAY_V (ra0
) : ra0
);
1548 /* Check to see if order might matter.
1549 This might be an argument for a separate
1550 SERIAL-ARRAY-MAP! */
1551 if (v0
== ra1
|| (SCM_ARRAYP (ra1
) && v0
== SCM_ARRAY_V (ra1
)))
1552 if (ra0
!= ra1
|| (SCM_ARRAYP(ra0
) && !SCM_ARRAY_CONTP(ra0
)))
1554 for (tail
= SCM_CDR (lra
); SCM_NNULLP (tail
); tail
= SCM_CDR (tail
))
1556 ra1
= SCM_CAR (tail
);
1557 if (v0
== ra1
|| (SCM_ARRAYP (ra1
) && v0
== SCM_ARRAY_V (ra1
)))
1560 for (p
= ra_asubrs
; p
->name
; p
++)
1561 if (proc
== p
->sproc
)
1563 if (ra0
!= SCM_CAR (lra
))
1564 scm_ramapc (scm_array_identity
, SCM_UNDEFINED
, ra0
, scm_cons (SCM_CAR (lra
), SCM_EOL
), FUNC_NAME
);
1565 lra
= SCM_CDR (lra
);
1568 scm_ramapc (p
->vproc
, SCM_UNDEFINED
, ra0
, lra
, FUNC_NAME
);
1569 if (SCM_IMP (lra
) || SCM_IMP (SCM_CDR (lra
)))
1570 return SCM_UNSPECIFIED
;
1571 lra
= SCM_CDR (lra
);
1574 scm_ramapc (ramap_2o
, proc
, ra0
, lra
, FUNC_NAME
);
1575 lra
= SCM_CDR (lra
);
1577 for (lra
= SCM_CDR (lra
); SCM_NIMP (lra
); lra
= SCM_CDR (lra
))
1578 scm_ramapc (ramap_a
, proc
, ra0
, lra
, FUNC_NAME
);
1580 return SCM_UNSPECIFIED
;
1587 rafe (SCM ra0
,SCM proc
,SCM ras
)
1589 long i
= SCM_ARRAY_DIMS (ra0
)->lbnd
;
1590 scm_sizet i0
= SCM_ARRAY_BASE (ra0
);
1591 long inc0
= SCM_ARRAY_DIMS (ra0
)->inc
;
1592 long n
= SCM_ARRAY_DIMS (ra0
)->ubnd
;
1593 ra0
= SCM_ARRAY_V (ra0
);
1594 if (SCM_NULLP (ras
))
1595 for (; i
<= n
; i
++, i0
+= inc0
)
1596 scm_apply (proc
, scm_cvref (ra0
, i0
, SCM_UNDEFINED
), scm_listofnull
);
1599 SCM ra1
= SCM_CAR (ras
);
1600 SCM args
, *ve
= &ras
;
1601 scm_sizet k
, i1
= SCM_ARRAY_BASE (ra1
);
1602 long inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1603 ra1
= SCM_ARRAY_V (ra1
);
1604 ras
= SCM_CDR (ras
);
1609 ras
= scm_vector (ras
);
1610 ve
= SCM_VELTS (ras
);
1612 for (; i
<= n
; i
++, i0
+= inc0
, i1
+= inc1
)
1615 for (k
= SCM_LENGTH (ras
); k
--;)
1616 args
= scm_cons (scm_uniform_vector_ref (ve
[k
], SCM_MAKINUM (i
)), args
);
1617 args
= scm_cons2 (scm_cvref (ra0
, i0
, SCM_UNDEFINED
), scm_cvref (ra1
, i1
, SCM_UNDEFINED
), args
);
1618 scm_apply (proc
, args
, SCM_EOL
);
1625 SCM_DEFINE (scm_array_for_each
, "array-for-each", 2, 0, 1,
1626 (SCM proc
, SCM ra0
, SCM lra
),
1627 "@var{proc} is applied to each tuple of elements of @var{array0} @dots{}\n"
1628 "in row-major order. The value returned is unspecified.")
1629 #define FUNC_NAME s_scm_array_for_each
1631 SCM_VALIDATE_PROC (1,proc
);
1632 scm_ramapc (rafe
, proc
, ra0
, lra
, FUNC_NAME
);
1633 return SCM_UNSPECIFIED
;
1637 SCM_DEFINE (scm_array_index_map_x
, "array-index-map!", 2, 0, 0,
1639 "applies @var{proc} to the indices of each element of @var{array} in\n"
1640 "turn, storing the result in the corresponding element. The value\n"
1641 "returned and the order of application are unspecified.\n\n"
1642 "One can implement @var{array-indexes} as\n"
1644 "(define (array-indexes array)\n"
1645 " (let ((ra (apply make-array #f (array-shape array))))\n"
1646 " (array-index-map! ra (lambda x x))\n"
1649 "Another example:\n"
1651 "(define (apl:index-generator n)\n"
1652 " (let ((v (make-uniform-vector n 1)))\n"
1653 " (array-index-map! v (lambda (i) i))\n"
1656 #define FUNC_NAME s_scm_array_index_map_x
1659 SCM_VALIDATE_NIM (1,ra
);
1660 SCM_VALIDATE_PROC (2,proc
);
1661 switch (SCM_TYP7(ra
))
1664 badarg
:SCM_WTA (1,ra
);
1665 case scm_tc7_vector
:
1668 SCM
*ve
= SCM_VELTS (ra
);
1669 for (i
= 0; i
< SCM_LENGTH (ra
); i
++)
1670 ve
[i
] = scm_apply (proc
, SCM_MAKINUM (i
), scm_listofnull
);
1671 return SCM_UNSPECIFIED
;
1673 case scm_tc7_string
:
1674 case scm_tc7_byvect
:
1679 #ifdef HAVE_LONG_LONGS
1680 case scm_tc7_llvect
:
1685 for (i
= 0; i
< SCM_LENGTH (ra
); i
++)
1686 scm_array_set_x (ra
, scm_apply (proc
, SCM_MAKINUM (i
), scm_listofnull
),
1688 return SCM_UNSPECIFIED
;
1690 SCM_ASRTGO (SCM_ARRAYP (ra
), badarg
);
1693 SCM inds
= scm_make_uve (SCM_ARRAY_NDIM (ra
), SCM_MAKINUM (-1L));
1694 long *vinds
= (long *) SCM_VELTS (inds
);
1695 int j
, k
, kmax
= SCM_ARRAY_NDIM (ra
) - 1;
1697 return scm_array_set_x (ra
, scm_apply(proc
, SCM_EOL
, SCM_EOL
),
1699 for (k
= 0; k
<= kmax
; k
++)
1700 vinds
[k
] = SCM_ARRAY_DIMS (ra
)[k
].lbnd
;
1706 vinds
[k
] = SCM_ARRAY_DIMS (ra
)[k
].lbnd
;
1707 i
= cind (ra
, inds
);
1708 for (; vinds
[k
] <= SCM_ARRAY_DIMS (ra
)[k
].ubnd
; vinds
[k
]++)
1710 for (j
= kmax
+ 1, args
= SCM_EOL
; j
--;)
1711 args
= scm_cons (SCM_MAKINUM (vinds
[j
]), args
);
1712 scm_array_set_x (SCM_ARRAY_V (ra
),
1713 scm_apply (proc
, args
, SCM_EOL
),
1715 i
+= SCM_ARRAY_DIMS (ra
)[k
].inc
;
1720 if (vinds
[k
] < SCM_ARRAY_DIMS (ra
)[k
].ubnd
)
1726 vinds
[k
] = SCM_ARRAY_DIMS (ra
)[k
].lbnd
- 1;
1730 return SCM_UNSPECIFIED
;
1738 raeql_1 (SCM ra0
,SCM as_equal
,SCM ra1
)
1740 SCM e0
= SCM_UNDEFINED
, e1
= SCM_UNDEFINED
;
1741 scm_sizet i0
= 0, i1
= 0;
1742 long inc0
= 1, inc1
= 1;
1743 scm_sizet n
= SCM_LENGTH (ra0
);
1744 ra1
= SCM_CAR (ra1
);
1745 if (SCM_ARRAYP(ra0
))
1747 n
= SCM_ARRAY_DIMS (ra0
)->ubnd
- SCM_ARRAY_DIMS (ra0
)->lbnd
+ 1;
1748 i0
= SCM_ARRAY_BASE (ra0
);
1749 inc0
= SCM_ARRAY_DIMS (ra0
)->inc
;
1750 ra0
= SCM_ARRAY_V (ra0
);
1752 if (SCM_ARRAYP (ra1
))
1754 i1
= SCM_ARRAY_BASE (ra1
);
1755 inc1
= SCM_ARRAY_DIMS (ra1
)->inc
;
1756 ra1
= SCM_ARRAY_V (ra1
);
1758 switch (SCM_TYP7 (ra0
))
1760 case scm_tc7_vector
:
1763 for (; n
--; i0
+= inc0
, i1
+= inc1
)
1765 if (SCM_FALSEP (as_equal
))
1767 if (SCM_FALSEP (scm_array_equal_p (RVREF (ra0
, i0
, e0
), RVREF (ra1
, i1
, e1
))))
1770 else if (SCM_FALSEP (scm_equal_p (RVREF (ra0
, i0
, e0
), RVREF (ra1
, i1
, e1
))))
1774 case scm_tc7_string
:
1775 case scm_tc7_byvect
:
1777 char *v0
= SCM_CHARS (ra0
) + i0
;
1778 char *v1
= SCM_CHARS (ra1
) + i1
;
1779 for (; n
--; v0
+= inc0
, v1
+= inc1
)
1785 for (; n
--; i0
+= inc0
, i1
+= inc1
)
1786 if (SCM_BITVEC_REF (ra0
, i0
) != SCM_BITVEC_REF (ra1
, i1
))
1792 long *v0
= (long *) SCM_VELTS (ra0
) + i0
;
1793 long *v1
= (long *) SCM_VELTS (ra1
) + i1
;
1794 for (; n
--; v0
+= inc0
, v1
+= inc1
)
1801 short *v0
= (short *) SCM_VELTS (ra0
) + i0
;
1802 short *v1
= (short *) SCM_VELTS (ra1
) + i1
;
1803 for (; n
--; v0
+= inc0
, v1
+= inc1
)
1808 #ifdef HAVE_LONG_LONGS
1809 case scm_tc7_llvect
:
1811 long long *v0
= (long long *) SCM_VELTS (ra0
) + i0
;
1812 long long *v1
= (long long *) SCM_VELTS (ra1
) + i1
;
1813 for (; n
--; v0
+= inc0
, v1
+= inc1
)
1821 float *v0
= (float *) SCM_VELTS (ra0
) + i0
;
1822 float *v1
= (float *) SCM_VELTS (ra1
) + i1
;
1823 for (; n
--; v0
+= inc0
, v1
+= inc1
)
1830 double *v0
= (double *) SCM_VELTS (ra0
) + i0
;
1831 double *v1
= (double *) SCM_VELTS (ra1
) + i1
;
1832 for (; n
--; v0
+= inc0
, v1
+= inc1
)
1839 double (*v0
)[2] = (double (*)[2]) SCM_VELTS (ra0
) + i0
;
1840 double (*v1
)[2] = (double (*)[2]) SCM_VELTS (ra1
) + i1
;
1841 for (; n
--; v0
+= inc0
, v1
+= inc1
)
1843 if ((*v0
)[0] != (*v1
)[0])
1845 if ((*v0
)[1] != (*v1
)[1])
1856 raeql (SCM ra0
,SCM as_equal
,SCM ra1
)
1858 SCM v0
= ra0
, v1
= ra1
;
1859 scm_array_dim dim0
, dim1
;
1860 scm_array_dim
*s0
= &dim0
, *s1
= &dim1
;
1861 scm_sizet bas0
= 0, bas1
= 0;
1862 int k
, unroll
= 1, vlen
= 1, ndim
= 1;
1863 if (SCM_ARRAYP (ra0
))
1865 ndim
= SCM_ARRAY_NDIM (ra0
);
1866 s0
= SCM_ARRAY_DIMS (ra0
);
1867 bas0
= SCM_ARRAY_BASE (ra0
);
1868 v0
= SCM_ARRAY_V (ra0
);
1874 s0
->ubnd
= SCM_LENGTH (v0
) - 1;
1877 if (SCM_ARRAYP (ra1
))
1879 if (ndim
!= SCM_ARRAY_NDIM (ra1
))
1881 s1
= SCM_ARRAY_DIMS (ra1
);
1882 bas1
= SCM_ARRAY_BASE (ra1
);
1883 v1
= SCM_ARRAY_V (ra1
);
1888 Huh ? Schizophrenic return type. --hwn
1894 s1
->ubnd
= SCM_LENGTH (v1
) - 1;
1897 if (SCM_TYP7 (v0
) != SCM_TYP7 (v1
))
1899 for (k
= ndim
; k
--;)
1901 if (s0
[k
].lbnd
!= s1
[k
].lbnd
|| s0
[k
].ubnd
!= s1
[k
].ubnd
)
1905 unroll
= (s0
[k
].inc
== s1
[k
].inc
);
1906 vlen
*= s0
[k
].ubnd
- s1
[k
].lbnd
+ 1;
1909 if (unroll
&& bas0
== bas1
&& v0
== v1
)
1911 return scm_ramapc (raeql_1
, as_equal
, ra0
, scm_cons (ra1
, SCM_EOL
), "");
1916 scm_raequal (SCM ra0
, SCM ra1
)
1918 return SCM_BOOL(raeql (ra0
, SCM_BOOL_T
, ra1
));
1922 /* GJB:FIXME:: Why not use SCM_DEFINE1 for array-equal? */
1923 SCM_DEFINE1 (scm_array_equal_p
, "array-equal?", scm_tc7_rpsubr
,
1925 "Returns @code{#t} iff all arguments are arrays with the same shape, the\n"
1926 "same type, and have corresponding elements which are either\n"
1927 "@code{equal?} or @code{array-equal?}. This function differs from\n"
1928 "@code{equal?} in that a one dimensional shared array may be\n"
1929 "@var{array-equal?} but not @var{equal?} to a vector or uniform vector.")
1930 #define FUNC_NAME s_scm_array_equal_p
1936 static char s_array_equal_p
[] = "array-equal?";
1940 scm_array_equal_p (SCM ra0
, SCM ra1
)
1942 if (SCM_IMP (ra0
) || SCM_IMP (ra1
))
1943 callequal
:return scm_equal_p (ra0
, ra1
);
1944 switch (SCM_TYP7(ra0
))
1949 case scm_tc7_string
:
1950 case scm_tc7_byvect
:
1956 case scm_tc7_vector
:
1960 if (!SCM_ARRAYP (ra0
))
1963 switch (SCM_TYP7 (ra1
))
1968 case scm_tc7_string
:
1969 case scm_tc7_byvect
:
1975 case scm_tc7_vector
:
1979 if (!SCM_ARRAYP (ra1
))
1982 return SCM_BOOL(raeql (ra0
, SCM_BOOL_F
, ra1
));
1988 init_raprocs (ra_iproc
*subra
)
1990 for (; subra
->name
; subra
++)
1991 subra
->sproc
= SCM_CDR (scm_intern (subra
->name
, strlen (subra
->name
)));
1998 init_raprocs (ra_rpsubrs
);
1999 init_raprocs (ra_asubrs
);
2000 scm_make_subr (s_array_equal_p
, scm_tc7_rpsubr
, scm_array_equal_p
);
2001 scm_smobs
[0x0ff & (scm_tc16_array
>> 8)].equalp
= scm_raequal
;
2003 scm_add_feature (s_scm_array_for_each
);