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