Marco Antoniotti
8/19/2015 4:23:00 PM
On Wednesday, August 19, 2015 at 5:16:47 PM UTC+3, Kaz Kylheku wrote:
> On 2015-08-19, Marco Antoniotti <marcoxa@gmail.com> wrote:
> > On Tuesday, August 18, 2015 at 5:45:07 PM UTC+3, Alexandre Landi wrote:
> >> Let's suppose I have an array - which I will call *my-array* - that looks like this:
> >>
> >> #2A((1 2 3)
> >> (4 5 6)
> >> (7 8 9))
> >>
> >> and I wish to apply some function f on the subarray
> >>
> >> #2A((5 6)
> >> (8 9))
> >>
> >> I'd love to be able to write
> >>
> >> (f (subarray *my-array* '(1 2) '(1 2))
> >>
> >> where the subarray function takes as arguments:
> >>
> >> - the original array
> >> - a 2-element list with starting point and ending point on the 1st dimension
> >> - another 2-element list with starting point and ending point on the 2nd dimension
> >> - etc.
> >>
> >> I am looking for some way to pass the subarray as argument to function f by
> >> reference (or by pointer?) instead of by value.
> >>
> >> (The dumb way to address this would be to write a function that creates (in
> >> this specific case) a 2*2 array and loops over i and j copying values from
> >> the original array. However, if you are dealing relatively large arrays,
> >> this would be quite costly.)
> >>
> >> I found there exists a cl-slice package but I do not get whether it copies
> >> values or accesses data by reference.
> >
> > The CL-SLICE package (thank you! :) ) copies when it cannot displace. AFAIK
> > there are no "mainstream" languages that do not copy when slicing a
> > n-dimensional array. The reason is that arrays (matrices) are usually kept
> > in row-major order (CL, C/C++ etc) or in column-major order (FORTRAN and
> > whatever uses FORTRAN as a base: R and Matlab come to mind).
>
> That's hardly a reason. If you want non-copying slicing badly enough, you
> can make it work for a sparse hash table, even.
>
> Every entry in the slice view can independently alias the corresponding
> original location, if such extremes are necessary.
>
> A displacement from one array to another, regardless of the number of
> dimensions, is basically just a coordinate transform with bounds checking.
>
> 1. Check that the coordinates are in the aliased view, else reject.
> 2. Apply coordinate transformation.
> 3. Check that the coordinates are in the target array, else reject (if
> out-of-bounds slices are allowed, or targets can be resized after a slice is
> created, so that views become partially or wholly out-of-bounds).
> 4. Delegate the access to the target array.
>
> No knowledge of the storage implementation of the target array should
> be required, other than for clever optimizing.
All of this is fine but it is not displacing in the Common Lisp sense (or in the FORTRAN sense, if available; my FORTRAN-fu is quite low).
Given the row-major layout of CL arrays you can get some form of "displacing" in certain cases.
As for the rest, you have to resort to this or that trick (PJB uses closures) to do the coordinate transform. That is what CL-SLICE does.
Cheers
--
MA