From: Rock
Subject: multidimensional array slices
Date: 
Message-ID: <7f7d1798-ab35-42c2-af7a-49ae0043884a@e10g2000vbe.googlegroups.com>
I know we've got subsequence but what if you need slices of
multidimensional arrays like in MATLAB or Fortan? Is there some
library, macro or anything for Common Lisp to do this?

Thanks.

Rock

From: Tamas K Papp
Subject: Re: multidimensional array slices
Date: 
Message-ID: <6vjo17FkipqtU1@mid.individual.net>
On Thu, 12 Feb 2009 14:09:50 -0800, Rock wrote:

> I know we've got subsequence but what if you need slices of
> multidimensional arrays like in MATLAB or Fortan? Is there some library,
> macro or anything for Common Lisp to do this?

What do you need it for, exactly?

You can displace an array and implement some "slicing" that way -
although it is not as general as Matlab's slices, I have always found
that I can organize my computation so that this suffices.

If you want the general slices, I wrote an experimental (but working)
package which might do what you want.  You can find it here:

http://www.princeton.edu/~tpapp/index.html#affi

Feedback is appreciated.

Tamas
From: Marco Antoniotti
Subject: Re: multidimensional array slices
Date: 
Message-ID: <803fd6ad-8477-4ccc-a17c-a1eb043c3b41@k8g2000yqn.googlegroups.com>
On Feb 12, 11:09 pm, Rock <···········@gmail.com> wrote:
> I know we've got subsequence but what if you need slices of
> multidimensional arrays like in MATLAB or Fortan? Is there some
> library, macro or anything for Common Lisp to do this?
>
> Thanks.
>
> Rock

I have something along the lines you ask for (and there are other
libraries floating around as well).  I cannot post it on Google
Groups.

This are the doc string of the main struct and constructor.

Structure ARRAY-SLICE
  "The ARRAY-SLICE Structure Class.
The ARRAY-SLICE structure class is used to select a subset of an
array.  ARRAY-SLICEs are most useful for multidimensional arrays,
where the displacing machinery is not sufficient, given the
constraints imposed by the requirements of the row major layout of
arrays.

Example:

Given A33 = #2A((1 2 3) (4 5 6) (7 8 9))

   (make-array-slice '(2 2) A33)
   => #2A((1 2) (4 5))

   (make-array-slice '(2 2) A33 '(1 0))
   => #2A((4 5) (7 8))

Caveats: printing an ARRAY-SLICE does allocate a new array; this will
be corrected in a future release."

Function MAKE-ARRAY-SLICE
  "Constructs a `slice' of array ARRAY.
The array slice will have dimensions DIMENSIONS and rank equal to the
rank of ARRAY.  The `origin' of the slice is set to OFFSETS, which, if
supplied, must be a list of indexes within ARRAY.

No space occupied by ARRAY is copied by this operation."

Send me an email and will send you the code.

Cheers
--
Marco
From: William James
Subject: Re: multidimensional array slices
Date: 
Message-ID: <gn3f69029ae@enews5.newsguy.com>
Marco Antoniotti wrote:

> On Feb 12, 11:09�pm, Rock <···········@gmail.com> wrote:
> > I know we've got subsequence but what if you need slices of
> > multidimensional arrays like in MATLAB or Fortan? Is there some
> > library, macro or anything for Common Lisp to do this?
> > 
> > Thanks.
> > 
> > Rock
> 
> I have something along the lines you ask for (and there are other
> libraries floating around as well).  I cannot post it on Google
> Groups.
> 
> This are the doc string of the main struct and constructor.
> 
> Structure ARRAY-SLICE
>   "The ARRAY-SLICE Structure Class.
> The ARRAY-SLICE structure class is used to select a subset of an
> array.  ARRAY-SLICEs are most useful for multidimensional arrays,
> where the displacing machinery is not sufficient, given the
> constraints imposed by the requirements of the row major layout of
> arrays.
> 
> Example:
> 
> Given A33 = #2A((1 2 3) (4 5 6) (7 8 9))
> 
>    (make-array-slice '(2 2) A33)
>    => #2A((1 2) (4 5))
> 
>    (make-array-slice '(2 2) A33 '(1 0))
>    => #2A((4 5) (7 8))
> 
> Caveats: printing an ARRAY-SLICE does allocate a new array; this will
> be corrected in a future release."
> 
> Function MAKE-ARRAY-SLICE
>   "Constructs a `slice' of array ARRAY.
> The array slice will have dimensions DIMENSIONS and rank equal to the
> rank of ARRAY.  The `origin' of the slice is set to OFFSETS, which, if
> supplied, must be a list of indexes within ARRAY.
> 
> No space occupied by ARRAY is copied by this operation."


Thanks for the entertaining problem.

Ruby:

class Array
  def make_array_slice( spans, offsets = nil )
    offsets ||= [0] * spans.size
    result = self[ offsets[0], spans[0] ]
    if spans.size > 1
      result.map{|x|
        x.make_array_slice( spans[1..-1], offsets[1..-1] ) }
    else
      result
    end
  end
end

a = (2..9).to_a
p a.make_array_slice( [3] )
p a.make_array_slice( [3], [2] )

a = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
p a.make_array_slice( [3,2] )
p a.make_array_slice( [3,2], [1,0] )

a = [ [[1,2,3,4], [3,4,5,6], [5,6,7,8]],
      [[7,8,9,10], [9,10,11,12], [11,12,13,14]],
      [[13,14,15,16], [15,16,17,18], [17,18,19,20]] ]
p a.make_array_slice( [2,2,3], [1,1,1] )

--- output ---
[2, 3, 4]
[4, 5, 6]
[[1, 2], [4, 5], [7, 8]]
[[4, 5], [7, 8], [10, 11]]
[[[10, 11, 12], [12, 13, 14]], [[16, 17, 18], [18, 19, 20]]]
From: Marco Antoniotti
Subject: Re: multidimensional array slices
Date: 
Message-ID: <6614c909-db69-4977-b587-b675a1f91f6d@u13g2000yqg.googlegroups.com>
On Feb 13, 10:40 am, "William James" <·········@yahoo.com> wrote:
> Marco Antoniotti wrote:
> > On Feb 12, 11:09 pm, Rock <···········@gmail.com> wrote:
> > > I know we've got subsequence but what if you need slices of
> > > multidimensional arrays like in MATLAB or Fortan? Is there some
> > > library, macro or anything for Common Lisp to do this?
>
> > > Thanks.
>
> > > Rock
>
> > I have something along the lines you ask for (and there are other
> > libraries floating around as well).  I cannot post it on Google
> > Groups.
>
> > This are the doc string of the main struct and constructor.
>
> > Structure ARRAY-SLICE
> >   "The ARRAY-SLICE Structure Class.
> > The ARRAY-SLICE structure class is used to select a subset of an
> > array.  ARRAY-SLICEs are most useful for multidimensional arrays,
> > where the displacing machinery is not sufficient, given the
> > constraints imposed by the requirements of the row major layout of
> > arrays.
>
> > Example:
>
> > Given A33 = #2A((1 2 3) (4 5 6) (7 8 9))
>
> >    (make-array-slice '(2 2) A33)
> >    => #2A((1 2) (4 5))
>
> >    (make-array-slice '(2 2) A33 '(1 0))
> >    => #2A((4 5) (7 8))
>
> > Caveats: printing an ARRAY-SLICE does allocate a new array; this will
> > be corrected in a future release."
>
> > Function MAKE-ARRAY-SLICE
> >   "Constructs a `slice' of array ARRAY.
> > The array slice will have dimensions DIMENSIONS and rank equal to the
> > rank of ARRAY.  The `origin' of the slice is set to OFFSETS, which, if
> > supplied, must be a list of indexes within ARRAY.
>
> > No space occupied by ARRAY is copied by this operation."
>
> Thanks for the entertaining problem.
>
> Ruby:
>
> class Array
>   def make_array_slice( spans, offsets = nil )
>     offsets ||= [0] * spans.size
>     result = self[ offsets[0], spans[0] ]
>     if spans.size > 1
>       result.map{|x|
>         x.make_array_slice( spans[1..-1], offsets[1..-1] ) }
>     else
>       result
>     end
>   end
> end
>
> a = (2..9).to_a
> p a.make_array_slice( [3] )
> p a.make_array_slice( [3], [2] )
>
> a = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
> p a.make_array_slice( [3,2] )
> p a.make_array_slice( [3,2], [1,0] )
>
> a = [ [[1,2,3,4], [3,4,5,6], [5,6,7,8]],
>       [[7,8,9,10], [9,10,11,12], [11,12,13,14]],
>       [[13,14,15,16], [15,16,17,18], [17,18,19,20]] ]
> p a.make_array_slice( [2,2,3], [1,1,1] )
>
> --- output ---
> [2, 3, 4]
> [4, 5, 6]
> [[1, 2], [4, 5], [7, 8]]
> [[4, 5], [7, 8], [10, 11]]
> [[[10, 11, 12], [12, 13, 14]], [[16, 17, 18], [18, 19, 20]]]

Cute, but it does not implement the spec.  You are copying the array
over and over.  The doc string explicitely says "No space occupied by
ARRAY is copied by this operation."

Cheers
--
Marco
From: Chaitanya Gupta
Subject: Re: multidimensional array slices
Date: 
Message-ID: <gn4dsr$2bu$1@news.motzarella.org>
Marco Antoniotti wrote:
> I have something along the lines you ask for (and there are other
> libraries floating around as well).  I cannot post it on Google
> Groups.
> 

I was looking for something similar a while ago. I guess there could be 
others too (besides the OP). Can you host it somewhere?

Chaitanya

> This are the doc string of the main struct and constructor.
> 
> Structure ARRAY-SLICE
>   "The ARRAY-SLICE Structure Class.
> The ARRAY-SLICE structure class is used to select a subset of an
> array.  ARRAY-SLICEs are most useful for multidimensional arrays,
> where the displacing machinery is not sufficient, given the
> constraints imposed by the requirements of the row major layout of
> arrays.
> 
> Example:
> 
> Given A33 = #2A((1 2 3) (4 5 6) (7 8 9))
> 
>    (make-array-slice '(2 2) A33)
>    => #2A((1 2) (4 5))
> 
>    (make-array-slice '(2 2) A33 '(1 0))
>    => #2A((4 5) (7 8))
> 
> Caveats: printing an ARRAY-SLICE does allocate a new array; this will
> be corrected in a future release."
> 
> Function MAKE-ARRAY-SLICE
>   "Constructs a `slice' of array ARRAY.
> The array slice will have dimensions DIMENSIONS and rank equal to the
> rank of ARRAY.  The `origin' of the slice is set to OFFSETS, which, if
> supplied, must be a list of indexes within ARRAY.
> 
> No space occupied by ARRAY is copied by this operation."
> 
> Send me an email and will send you the code.
> 
> Cheers
> --
> Marco
> 
From: William James
Subject: Re: multidimensional array slices
Date: 
Message-ID: <gnn5n4015qh@enews5.newsguy.com>
Marco Antoniotti wrote:

> On Feb 12, 11:09�pm, Rock <···········@gmail.com> wrote:
> > I know we've got subsequence but what if you need slices of
> > multidimensional arrays like in MATLAB or Fortan? Is there some
> > library, macro or anything for Common Lisp to do this?
> > 
> > Thanks.
> > 
> > Rock
> 
> I have something along the lines you ask for (and there are other
> libraries floating around as well).  I cannot post it on Google
> Groups.
> 
> This are the doc string of the main struct and constructor.
> 
> Structure ARRAY-SLICE
>   "The ARRAY-SLICE Structure Class.
> The ARRAY-SLICE structure class is used to select a subset of an
> array.  ARRAY-SLICEs are most useful for multidimensional arrays,
> where the displacing machinery is not sufficient, given the
> constraints imposed by the requirements of the row major layout of
> arrays.
> 
> Example:
> 
> Given A33 = #2A((1 2 3) (4 5 6) (7 8 9))
> 
>    (make-array-slice '(2 2) A33)
>    => #2A((1 2) (4 5))
> 
>    (make-array-slice '(2 2) A33 '(1 0))
>    => #2A((4 5) (7 8))
> 
> Caveats: printing an ARRAY-SLICE does allocate a new array; this will
> be corrected in a future release."
> 
> Function MAKE-ARRAY-SLICE
>   "Constructs a `slice' of array ARRAY.
> The array slice will have dimensions DIMENSIONS and rank equal to the
> rank of ARRAY.  The `origin' of the slice is set to OFFSETS, which, if
> supplied, must be a list of indexes within ARRAY.
> 

Clojure:

(defn make-vec-slice [spans v & offsets]
  (let [ offsets  (or (first offsets) (map (fn[x] 0) spans))
         result
           (subvec v (first offsets) (+ (first spans) (first offsets)))
       ]
    (if (rest spans)
      (vec (map #(make-vec-slice (rest spans) % (rest offsets)) result))
      result
    )))


user=> (def a (vec (range 2 10)))
#'user/a
user=> (make-vec-slice '(3) a)
[2 3 4]
user=> (make-vec-slice '(3) a '(2))
[4 5 6]

user=> (def a  [[1 2 3] [4 5 6] [7 8 9] [10 11 12]])
#'user/a
user=> (make-vec-slice '(3 2) a)
[[1 2] [4 5] [7 8]]
user=> (make-vec-slice '(3 2) a '(1 0))
[[4 5] [7 8] [10 11]]

user=> (def a [ [[1 2 3 4]  [3 4 5 6]  [5 6 7 8]]
      [[7 8 9 10]  [9 10 11 12]  [11 12 13 14]]
      [[13 14 15 16]  [15 16 17 18]  [17 18 19 20]] ] )
#'user/a
user=> (make-vec-slice '(2 2 3) a '(1 1 1))
[[[10 11 12] [12 13 14]] [[16 17 18] [18 19 20]]]
From: André Thieme
Subject: Re: multidimensional array slices
Date: 
Message-ID: <gnq65j$tbh$1@news.motzarella.org>
William James schrieb:
> Marco Antoniotti wrote:
> 
>> On Feb 12, 11:09 pm, Rock <···········@gmail.com> wrote:
>>> I know we've got subsequence but what if you need slices of
>>> multidimensional arrays like in MATLAB or Fortan? Is there some
>>> library, macro or anything for Common Lisp to do this?
>>>
>>> Thanks.
>>>
>>> Rock
>> I have something along the lines you ask for (and there are other
>> libraries floating around as well).  I cannot post it on Google
>> Groups.
>>
>> This are the doc string of the main struct and constructor.
>>
>> Structure ARRAY-SLICE
>>   "The ARRAY-SLICE Structure Class.
>> The ARRAY-SLICE structure class is used to select a subset of an
>> array.  ARRAY-SLICEs are most useful for multidimensional arrays,
>> where the displacing machinery is not sufficient, given the
>> constraints imposed by the requirements of the row major layout of
>> arrays.
>>
>> Example:
>>
>> Given A33 = #2A((1 2 3) (4 5 6) (7 8 9))
>>
>>    (make-array-slice '(2 2) A33)
>>    => #2A((1 2) (4 5))
>>
>>    (make-array-slice '(2 2) A33 '(1 0))
>>    => #2A((4 5) (7 8))
>>
>> Caveats: printing an ARRAY-SLICE does allocate a new array; this will
>> be corrected in a future release."
>>
>> Function MAKE-ARRAY-SLICE
>>   "Constructs a `slice' of array ARRAY.
>> The array slice will have dimensions DIMENSIONS and rank equal to the
>> rank of ARRAY.  The `origin' of the slice is set to OFFSETS, which, if
>> supplied, must be a list of indexes within ARRAY.
>>
> 
> Clojure:
> 
> (defn make-vec-slice [spans v & offsets]
>   (let [ offsets  (or (first offsets) (map (fn[x] 0) spans))
>          result
>            (subvec v (first offsets) (+ (first spans) (first offsets)))
>        ]
>     (if (rest spans)
>       (vec (map #(make-vec-slice (rest spans) % (rest offsets)) result))
>       result
>     )))

In your let you could use destructuring. An example:
user> (let [[a b & c :as all] (range 10)]
         (println a)
         (println b)
         (println c)
         (println all))
0
1
(2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)

So, spans is only used in your code in combination with either first or
rest. We could call the first of spans fs and the rest rs.
(let [[fs & rs] spans] ...)
And similar with offsets. First offset could be fo and (rest offsets) ro:

(defn make-vec-slice [spans v & offsets]
   (let [[fs & rs] spans
         [fo & ro] (or (first offsets) (map (constantly 0) spans))
         result (subvec v fo (+ fs fo))]
     (if-not rs
       result
       (vec (map #(make-vec-slice rs % ro) result)))))

In short functions it�s okay to use these abbreviations. The reader will
immediately see what they mean.
I did not test that code, maybe there is a typo in there.

Instead of
(map (fn [x] 0) spans)      or
(map (constantly 0) spans)  one could also say:
(for [_ spans] 0)

The _ is just a normal variable name and it could have been x as well.
But it is idiomatic to use the underscore in Clojure for throw-away args.
I personally like to see the easier/short case in an if first, so that�s
why I used if-not (now result is THEN and not ELSE).


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: William James
Subject: Re: multidimensional array slices
Date: 
Message-ID: <gnq9120qr9@enews5.newsguy.com>
Andr� Thieme wrote:

> William James schrieb:
> > Marco Antoniotti wrote:
> > 
> >>On Feb 12, 11:09 pm, Rock <···········@gmail.com> wrote:
> > > > I know we've got subsequence but what if you need slices of
> > > > multidimensional arrays like in MATLAB or Fortan? Is there some
> > > > library, macro or anything for Common Lisp to do this?
> > > > 
> > > > Thanks.
> > > > 
> > > > Rock
> > > I have something along the lines you ask for (and there are other
> > > libraries floating around as well).  I cannot post it on Google
> > > Groups.
> > > 
> > > This are the doc string of the main struct and constructor.
> > > 
> > > Structure ARRAY-SLICE
> >>  "The ARRAY-SLICE Structure Class.
> > > The ARRAY-SLICE structure class is used to select a subset of an
> > > array.  ARRAY-SLICEs are most useful for multidimensional arrays,
> > > where the displacing machinery is not sufficient, given the
> > > constraints imposed by the requirements of the row major layout of
> > > arrays.
> > > 
> > > Example:
> > > 
> > > Given A33 = #2A((1 2 3) (4 5 6) (7 8 9))
> > > 
> >>   (make-array-slice '(2 2) A33)
> >>   => #2A((1 2) (4 5))
> > > 
> >>   (make-array-slice '(2 2) A33 '(1 0))
> >>   => #2A((4 5) (7 8))
> > > 
> > > Caveats: printing an ARRAY-SLICE does allocate a new array; this
> > > will be corrected in a future release."
> > > 
> > > Function MAKE-ARRAY-SLICE
> >>  "Constructs a `slice' of array ARRAY.
> > > The array slice will have dimensions DIMENSIONS and rank equal to
> > > the rank of ARRAY.  The `origin' of the slice is set to OFFSETS,
> > > which, if supplied, must be a list of indexes within ARRAY.
> > > 
> > 
> > Clojure:
> > 
> > (defn make-vec-slice [spans v & offsets]
> >  (let [ offsets  (or (first offsets) (map (fn[x] 0) spans))
> >         result
> >           (subvec v (first offsets) (+ (first spans) (first
> > offsets)))       ]
> >    (if (rest spans)
> >      (vec (map #(make-vec-slice (rest spans) % (rest offsets))
> > result))      result
> >    )))
> 
> In your let you could use destructuring. An example:
> user> (let [[a b & c :as all] (range 10)]
>         (println a)
>         (println b)
>         (println c)
>         (println all))
> 0
> 1
> (2 3 4 5 6 7 8 9)
> (0 1 2 3 4 5 6 7 8 9)

Ruby:

irb(main):010:0> a, *b = [2,3,4,5]
=> [2, 3, 4, 5]
irb(main):011:0> a
=> 2
irb(main):012:0> b
=> [3, 4, 5]


> 
> So, spans is only used in your code in combination with either first
> or rest. We could call the first of spans fs and the rest rs.
> (let [[fs & rs] spans] ...)
> And similar with offsets. First offset could be fo and (rest offsets)
> ro:
> 
> (defn make-vec-slice [spans v & offsets]
>   (let [[fs & rs] spans
>         [fo & ro] (or (first offsets) (map (constantly 0) spans))
>         result (subvec v fo (+ fs fo))]
>     (if-not rs
>       result
>       (vec (map #(make-vec-slice rs % ro) result)))))
> 
> In short functions it�s okay to use these abbreviations. The reader
> will immediately see what they mean.
> I did not test that code, maybe there is a typo in there.
> 
> Instead of
> (map (fn [x] 0) spans)      or
> (map (constantly 0) spans)  one could also say:
> (for [_ spans] 0)

Ruby:

[0] * spans.size

> 
> The _ is just a normal variable name and it could have been x as well.
> But it is idiomatic to use the underscore in Clojure for throw-away
> args.  I personally like to see the easier/short case in an if first,
> so that�s why I used if-not (now result is THEN and not ELSE).
> 
> 
> Andr�


(defn make-vec-slice [spans v & offsets]
  (let [ [offset & offsets]  (or (first offsets) (for [_ spans] 0))
         [span & spans] spans
         result  (subvec v offset (+ span offset)) ]
    (if spans
      (vec (map #(make-vec-slice spans % offsets) result))
      result)))
From: André Thieme
Subject: Re: multidimensional array slices
Date: 
Message-ID: <gnqd8p$1pb$1@news.motzarella.org>
William James schrieb:
> Andr� Thieme wrote:
> 
>> William James schrieb:
>>> Marco Antoniotti wrote:
>>>
>>>> On Feb 12, 11:09 pm, Rock <···········@gmail.com> wrote:
>>>>> I know we've got subsequence but what if you need slices of
>>>>> multidimensional arrays like in MATLAB or Fortan? Is there some
>>>>> library, macro or anything for Common Lisp to do this?
>>>>>
>>>>> Thanks.
>>>>>
>>>>> Rock
>>>> I have something along the lines you ask for (and there are other
>>>> libraries floating around as well).  I cannot post it on Google
>>>> Groups.
>>>>
>>>> This are the doc string of the main struct and constructor.
>>>>
>>>> Structure ARRAY-SLICE
>>>>  "The ARRAY-SLICE Structure Class.
>>>> The ARRAY-SLICE structure class is used to select a subset of an
>>>> array.  ARRAY-SLICEs are most useful for multidimensional arrays,
>>>> where the displacing machinery is not sufficient, given the
>>>> constraints imposed by the requirements of the row major layout of
>>>> arrays.
>>>>
>>>> Example:
>>>>
>>>> Given A33 = #2A((1 2 3) (4 5 6) (7 8 9))
>>>>
>>>>   (make-array-slice '(2 2) A33)
>>>>   => #2A((1 2) (4 5))
>>>>
>>>>   (make-array-slice '(2 2) A33 '(1 0))
>>>>   => #2A((4 5) (7 8))
>>>>
>>>> Caveats: printing an ARRAY-SLICE does allocate a new array; this
>>>> will be corrected in a future release."
>>>>
>>>> Function MAKE-ARRAY-SLICE
>>>>  "Constructs a `slice' of array ARRAY.
>>>> The array slice will have dimensions DIMENSIONS and rank equal to
>>>> the rank of ARRAY.  The `origin' of the slice is set to OFFSETS,
>>>> which, if supplied, must be a list of indexes within ARRAY.
>>>>
>>> Clojure:
>>>
>>> (defn make-vec-slice [spans v & offsets]
>>>  (let [ offsets  (or (first offsets) (map (fn[x] 0) spans))
>>>         result
>>>           (subvec v (first offsets) (+ (first spans) (first
>>> offsets)))       ]
>>>    (if (rest spans)
>>>      (vec (map #(make-vec-slice (rest spans) % (rest offsets))
>>> result))      result
>>>    )))
>> In your let you could use destructuring. An example:
>> user> (let [[a b & c :as all] (range 10)]
>>         (println a)
>>         (println b)
>>         (println c)
>>         (println all))
>> 0
>> 1
>> (2 3 4 5 6 7 8 9)
>> (0 1 2 3 4 5 6 7 8 9)
> 
> Ruby:
> 
> irb(main):010:0> a, *b = [2,3,4,5]
> => [2, 3, 4, 5]
> irb(main):011:0> a
> => 2
> irb(main):012:0> b
> => [3, 4, 5]

Yes, it�s a bit shorter.
a, *b = [2, 3, 4, 5] ...    vs.
(let [[a & b] [2 3 4 5]] ...

I don�t have Ruby at hand right now.
Can it also in its current version do:
a, b, *c = "Hallo"  ?

(let [[a b & c] "Hallo"] (println a b c))

Destructuring also works for hashmaps.

>> So, spans is only used in your code in combination with either first
>> or rest. We could call the first of spans fs and the rest rs.
>> (let [[fs & rs] spans] ...)
>> And similar with offsets. First offset could be fo and (rest offsets)
>> ro:
>>
>> (defn make-vec-slice [spans v & offsets]
>>   (let [[fs & rs] spans
>>         [fo & ro] (or (first offsets) (map (constantly 0) spans))
>>         result (subvec v fo (+ fs fo))]
>>     (if-not rs
>>       result
>>       (vec (map #(make-vec-slice rs % ro) result)))))
>>
>> In short functions it�s okay to use these abbreviations. The reader
>> will immediately see what they mean.
>> I did not test that code, maybe there is a typo in there.
>>
>> Instead of
>> (map (fn [x] 0) spans)      or
>> (map (constantly 0) spans)  one could also say:
>> (for [_ spans] 0)
> 
> Ruby:
> 
> [0] * spans.size

(for [_ spans] 0) is one char longer.
I would write either (map (constantly 0) spans) or the (for [_ spans] 0).


> (defn make-vec-slice [spans v & offsets]
>   (let [ [offset & offsets]  (or (first offsets) (for [_ spans] 0))
>          [span & spans] spans
>          result  (subvec v offset (+ span offset)) ]
>     (if spans
>       (vec (map #(make-vec-slice spans % offsets) result))
>       result)))

Ok.


Andr�
-- 
Lisp is not dead. It�s just the URL that has changed:
http://clojure.org/
From: Marco Antoniotti
Subject: Re: multidimensional array slices
Date: 
Message-ID: <3ebb10a8-8efc-4fdb-83c5-c3d639616c0f@x10g2000yqk.googlegroups.com>
On Feb 22, 3:28 am, André Thieme <address.good.until.
···········@justmail.de> wrote:
> William James schrieb:
>
>
>
> > André Thieme wrote:
>
> >> William James schrieb:
> >>> Marco Antoniotti wrote:
>
> >>>> On Feb 12, 11:09 pm, Rock <···········@gmail.com> wrote:
> >>>>> I know we've got subsequence but what if you need slices of
> >>>>> multidimensional arrays like in MATLAB or Fortan? Is there some
> >>>>> library, macro or anything for Common Lisp to do this?
>
> >>>>> Thanks.
>
> >>>>> Rock
> >>>> I have something along the lines you ask for (and there are other
> >>>> libraries floating around as well).  I cannot post it on Google
> >>>> Groups.
>
> >>>> This are the doc string of the main struct and constructor.
>
> >>>> Structure ARRAY-SLICE
> >>>>  "The ARRAY-SLICE Structure Class.
> >>>> The ARRAY-SLICE structure class is used to select a subset of an
> >>>> array.  ARRAY-SLICEs are most useful for multidimensional arrays,
> >>>> where the displacing machinery is not sufficient, given the
> >>>> constraints imposed by the requirements of the row major layout of
> >>>> arrays.
>
> >>>> Example:
>
> >>>> Given A33 = #2A((1 2 3) (4 5 6) (7 8 9))
>
> >>>>   (make-array-slice '(2 2) A33)
> >>>>   => #2A((1 2) (4 5))
>
> >>>>   (make-array-slice '(2 2) A33 '(1 0))
> >>>>   => #2A((4 5) (7 8))
>
> >>>> Caveats: printing an ARRAY-SLICE does allocate a new array; this
> >>>> will be corrected in a future release."
>
> >>>> Function MAKE-ARRAY-SLICE
> >>>>  "Constructs a `slice' of array ARRAY.
> >>>> The array slice will have dimensions DIMENSIONS and rank equal to
> >>>> the rank of ARRAY.  The `origin' of the slice is set to OFFSETS,
> >>>> which, if supplied, must be a list of indexes within ARRAY.
>
> >>> Clojure:
>
> >>> (defn make-vec-slice [spans v & offsets]
> >>>  (let [ offsets  (or (first offsets) (map (fn[x] 0) spans))
> >>>         result
> >>>           (subvec v (first offsets) (+ (first spans) (first
> >>> offsets)))       ]
> >>>    (if (rest spans)
> >>>      (vec (map #(make-vec-slice (rest spans) % (rest offsets))
> >>> result))      result
> >>>    )))
> >> In your let you could use destructuring. An example:
> >> user> (let [[a b & c :as all] (range 10)]
> >>         (println a)
> >>         (println b)
> >>         (println c)
> >>         (println all))
> >> 0
> >> 1
> >> (2 3 4 5 6 7 8 9)
> >> (0 1 2 3 4 5 6 7 8 9)
>
> > Ruby:
>
> > irb(main):010:0> a, *b = [2,3,4,5]
> > => [2, 3, 4, 5]
> > irb(main):011:0> a
> > => 2
> > irb(main):012:0> b
> > => [3, 4, 5]
>
> Yes, it’s a bit shorter.
> a, *b = [2, 3, 4, 5] ...    vs.
> (let [[a & b] [2 3 4 5]] ...
>
> I don’t have Ruby at hand right now.
> Can it also in its current version do:
> a, b, *c = "Hallo"  ?
>
> (let [[a b & c] "Hallo"] (println a b c))

cl-prompt> (unify:match (#T(string ?a ?b &rest ?c) "Hallo") (values a
b c))
#\H
#\a
"llo"

Shameless plug:  CL-UNIFICATION.  Verbose, but working as
expected.  :)

Cheers
--
Marco





>
> Destructuring also works for hashmaps.
>
>
>
> >> So, spans is only used in your code in combination with either first
> >> or rest. We could call the first of spans fs and the rest rs.
> >> (let [[fs & rs] spans] ...)
> >> And similar with offsets. First offset could be fo and (rest offsets)
> >> ro:
>
> >> (defn make-vec-slice [spans v & offsets]
> >>   (let [[fs & rs] spans
> >>         [fo & ro] (or (first offsets) (map (constantly 0) spans))
> >>         result (subvec v fo (+ fs fo))]
> >>     (if-not rs
> >>       result
> >>       (vec (map #(make-vec-slice rs % ro) result)))))
>
> >> In short functions it’s okay to use these abbreviations. The reader
> >> will immediately see what they mean.
> >> I did not test that code, maybe there is a typo in there.
>
> >> Instead of
> >> (map (fn [x] 0) spans)      or
> >> (map (constantly 0) spans)  one could also say:
> >> (for [_ spans] 0)
>
> > Ruby:
>
> > [0] * spans.size
>
> (for [_ spans] 0) is one char longer.
> I would write either (map (constantly 0) spans) or the (for [_ spans] 0).
>
> > (defn make-vec-slice [spans v & offsets]
> >   (let [ [offset & offsets]  (or (first offsets) (for [_ spans] 0))
> >          [span & spans] spans
> >          result  (subvec v offset (+ span offset)) ]
> >     (if spans
> >       (vec (map #(make-vec-slice spans % offsets) result))
> >       result)))
>
> Ok.
>
> André
> --
> Lisp is not dead. It’s just the URL that has changed:http://clojure.org/
From: William James
Subject: Re: multidimensional array slices
Date: 
Message-ID: <gnqdvu01rhh@enews2.newsguy.com>
Andr� Thieme wrote:

> Can it also in its current version do:
> a, b, *c = "Hallo"  ?
> 
> (let [[a b & c] "Hallo"] (println a b c))

irb(main):007:0> a, *b = 'foobar'.split //
=> ["f", "o", "o", "b", "a", "r"]
irb(main):009:0> a
=> "f"
irb(main):010:0> b
=> ["o", "o", "b", "a", "r"]
From: William James
Subject: Re: multidimensional array slices
Date: 
Message-ID: <go0f160o3h@enews5.newsguy.com>
William James wrote:

> 
> 
> (defn make-vec-slice [spans v & offsets]
>   (let [ [offset & offsets]  (or (first offsets) (for [_ spans] 0))
>          [span & spans] spans
>          result  (subvec v offset (+ span offset)) ]
>     (if spans
>       (vec (map #(make-vec-slice spans % offsets) result))
>       result)))

(defn make-vec-slice
  ; Offsets weren't supplied.
  ([spans v]  (make-vec-slice spans v (repeat 0)))
  ; Offsets were supplied.
  ([spans v offsets]
    (let [ [span & spans] spans
           [offset & offsets] offsets
           result  (subvec v offset (+ span offset)) ]
      (if spans
        (vec (map #(make-vec-slice spans % offsets) result))
        result))))
From: Marco Antoniotti
Subject: Re: multidimensional array slices
Date: 
Message-ID: <a232d89a-6270-4b59-a51b-993a4fd2ae10@p13g2000yqc.googlegroups.com>
On Feb 20, 10:01 pm, "William James" <·········@yahoo.com> wrote:
> Marco Antoniotti wrote:
> > On Feb 12, 11:09 pm, Rock <···········@gmail.com> wrote:
> > > I know we've got subsequence but what if you need slices of
> > > multidimensional arrays like in MATLAB or Fortan? Is there some
> > > library, macro or anything for Common Lisp to do this?
>
> > > Thanks.
>
> > > Rock
>
> > I have something along the lines you ask for (and there are other
> > libraries floating around as well).  I cannot post it on Google
> > Groups.
>
> > This are the doc string of the main struct and constructor.
>
> > Structure ARRAY-SLICE
> >   "The ARRAY-SLICE Structure Class.
> > The ARRAY-SLICE structure class is used to select a subset of an
> > array.  ARRAY-SLICEs are most useful for multidimensional arrays,
> > where the displacing machinery is not sufficient, given the
> > constraints imposed by the requirements of the row major layout of
> > arrays.
>
> > Example:
>
> > Given A33 = #2A((1 2 3) (4 5 6) (7 8 9))
>
> >    (make-array-slice '(2 2) A33)
> >    => #2A((1 2) (4 5))
>
> >    (make-array-slice '(2 2) A33 '(1 0))
> >    => #2A((4 5) (7 8))
>
> > Caveats: printing an ARRAY-SLICE does allocate a new array; this will
> > be corrected in a future release."
>
> > Function MAKE-ARRAY-SLICE
> >   "Constructs a `slice' of array ARRAY.
> > The array slice will have dimensions DIMENSIONS and rank equal to the
> > rank of ARRAY.  The `origin' of the slice is set to OFFSETS, which, if
> > supplied, must be a list of indexes within ARRAY.
>
> Clojure:
>
> (defn make-vec-slice [spans v & offsets]
>   (let [ offsets  (or (first offsets) (map (fn[x] 0) spans))
>          result
>            (subvec v (first offsets) (+ (first spans) (first offsets)))
>        ]
>     (if (rest spans)
>       (vec (map #(make-vec-slice (rest spans) % (rest offsets)) result))
>       result
>     )))
>
> user=> (def a (vec (range 2 10)))
> #'user/a
> user=> (make-vec-slice '(3) a)
> [2 3 4]
> user=> (make-vec-slice '(3) a '(2))
> [4 5 6]
>
> user=> (def a  [[1 2 3] [4 5 6] [7 8 9] [10 11 12]])
> #'user/a
> user=> (make-vec-slice '(3 2) a)
> [[1 2] [4 5] [7 8]]
> user=> (make-vec-slice '(3 2) a '(1 0))
> [[4 5] [7 8] [10 11]]
>
> user=> (def a [ [[1 2 3 4]  [3 4 5 6]  [5 6 7 8]]
>       [[7 8 9 10]  [9 10 11 12]  [11 12 13 14]]
>       [[13 14 15 16]  [15 16 17 18]  [17 18 19 20]] ] )
> #'user/a
> user=> (make-vec-slice '(2 2 3) a '(1 1 1))
> [[[10 11 12] [12 13 14]] [[16 17 18] [18 19 20]]]

Cute again, but it ain't Ruby.

Cheers
--
Marco