unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* doc make-shared-array
@ 2005-02-11 22:14 Kevin Ryde
  2005-02-28  2:25 ` Marius Vollmer
  0 siblings, 1 reply; 2+ messages in thread
From: Kevin Ryde @ 2005-02-11 22:14 UTC (permalink / raw)


Expanded words about make-shared-array, trying to clarify what linear
means, and adding lots of example usages.

The examples make it a bit on the long side, it's worth it though,
since it's not easy to think of these usages if you don't already
know.  I'm thinking of splitting out a "shared arrays" section to
collect up shared array bits, and perhaps enclose-array too (if anyone
can explain what it actually does :-).

The quotient/remainder example flattening two dims to one works I
think, but I'm not sure it obeys a strict reading of what's described
for a "linear" mapfunc.  Maybe some description involving the actual
strides used in the implementation would be better.





 -- Scheme Procedure: make-shared-array oldarray mapfunc bound ...
 -- C Function: scm_make_shared_array (oldarray, mapfunc, boundlist)
     Return a new array which shares the storage of OLDARRAY.  Changes
     made through either affect the same underlying storage.  The
     BOUND... arguments are the shape of the new array, the same as
     `make-array' above.

     MAPFUNC translates coordinates from the new array to the OLDARRAY.
     It's called as `(MAPFUNC newidx1 ...)' with one parameter for
     each dimension of the new array, and should return a list of
     indices for OLDARRAY, one for each dimension of OLDARRAY.

     MAPFUNC must be linear, meaning that each OLDARRAY index must be
     formed by adding integer multiples (possibly negative) of some or
     all of NEWIDX1 etc, plus a possible integer offset.  The multiples
     and offset must be the same in each call.


     One good use for a shared array is to restrict the range of some
     dimensions, so as to apply say `array-for-each' or `array-fill!'
     to only part of an array.  The plain `list' function can be used
     for MAPFUNC in this case, making no changes to the index values.
     For example,

          (make-shared-array #2((a b c) (d e f) (g h i)) list 3 2)
          => #2((a b) (d e) (g h))

     The new array can have fewer dimensions than OLDARRAY, for example
     to take a column from an array.

          (make-shared-array #2((a b c) (d e f) (g h i))
                             (lambda (i) (list i 2))
                             '(0 2))
          => #1(c f i)

     A diagonal can be taken by using the single new array index for
     both row and column in the old array.  For example,

          (make-shared-array #2((a b c) (d e f) (g h i))
                             (lambda (i) (list i i))
                             '(0 2))
          => #1(a e i)

     An array can be flattened from say two dimensions to one by having
     the MAPFUNC translate portions of the new array to rows in the old,

          (make-shared-array #2((a b c d) (e f g h) (i j k l))
                             (lambda (i) (list (quotient i 4)
                                               (remainder i 4)))
                             12)
          => #(a b c d e f g h i j k l)

     The opposite is possible too, taking say a one dimensional array
     and considering portions of it as rows,

          (make-shared-array #1(a b c d e f g h i j k l)
                             (lambda (i j) (list (+ (* i 3) j)))
                             4 3)
          => #2((a b c) (d e f) (g h i) (j k l))

     With a negation on an index, the order that elements appear can be
     reversed.  This is the sort of thing `array-transpose' below does.
     The following just reverses the column order,

          (make-shared-array #2((a b c) (d e f) (g h i))
                             (lambda (i j) (list i (- 2 j)))
                             3 3)
          => #2((c b a) (f e d) (i h g))

     A fixed offset on indexes allows for instance a change from a 0
     based to a 1 based array,

          (define x #2((a b c) (d e f) (g h i)))
          (define y (make-shared-array x
                                       (lambda (i j) (list (1- i) (1- j)))
                                       '(1 3) '(1 3)))
          (array-ref x 0 0) => a
          (array-ref y 1 1) => a

     A multiple on an index allows every Nth element of an array to be
     taken.  The following is every third element,

          (make-shared-array #1(a b c d e f g h i j k l)
                             (lambda (i) (* i 3))
                             4)
          => #1(a d g j)

     The above examples can be combined to make weird and wonderful
     selections from an array, but it's important to note that because
     MAPFUNC must be linear, arbitrary permutations are not possible.

     In the current implementation, MAPFUNC is not called for every
     access to the new array but only on some sample points to
     establish a base and stride for new array indices in OLDARRAY
     data.  A few sample points are enough because MAPFUNC is linear.


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: doc make-shared-array
  2005-02-11 22:14 doc make-shared-array Kevin Ryde
@ 2005-02-28  2:25 ` Marius Vollmer
  0 siblings, 0 replies; 2+ messages in thread
From: Marius Vollmer @ 2005-02-28  2:25 UTC (permalink / raw)


Kevin Ryde <user42@zip.com.au> writes:

> Expanded words about make-shared-array, trying to clarify what linear
> means, and adding lots of example usages.

Nice, thanks!

> [...] and perhaps enclose-array too (if anyone can explain what it
> actually does :-).

Yeah, strange critters, those enclosed arrays.  Enclosing an array is
like creating a new array where each element is a shared array created
from the original array.  An enclosed array is different from this in
that the shared arrays are created 'on-demand' during array-ref.

> The quotient/remainder example flattening two dims to one works I
> think, but I'm not sure it obeys a strict reading of what's described
> for a "linear" mapfunc.

It is not linear (and not affine) and make-shared array only works by
accident in this case, I think.  For example, bounds checking is not
done independently for each dimension, but only for the start and end
points in the lexical ordering of all possible indices, or something
like that.

Also, the map function is not really linear, it is affine (because of
the offset).

>      An array can be flattened from say two dimensions to one by having
>      the MAPFUNC translate portions of the new array to rows in the old,
>
>           (make-shared-array #2((a b c d) (e f g h) (i j k l))
>                              (lambda (i) (list (quotient i 4)
>                                                (remainder i 4)))
>                              12)
>           => #(a b c d e f g h i j k l)

This should be removed.  An array can be flattened with
array-contents.

>      The opposite is possible too, taking say a one dimensional array
>      and considering portions of it as rows,
>
>           (make-shared-array #1(a b c d e f g h i j k l)
>                              (lambda (i j) (list (+ (* i 3) j)))
>                              4 3)
>           => #2((a b c) (d e f) (g h i) (j k l))

But this is OK, of course.

>      With a negation on an index, the order that elements appear can be
>      reversed.  This is the sort of thing `array-transpose' below does.

Hmm, transpose-array (not array-transpose) permutes the indices, it
does not reverse the direction within one dimension.

-- 
GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3  331E FAF8 226A D5D4 E405


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-02-28  2:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-11 22:14 doc make-shared-array Kevin Ryde
2005-02-28  2:25 ` Marius Vollmer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).