From: Marco Antoniotti
Subject: Changing the :DISPLACED-INDEX-OFFSET of a displaced array
Date: 
Message-ID: <5777bfab-6a4b-4817-8d1d-b412a71c0d5c@u72g2000hsf.googlegroups.com>
Hi

suppose I have a 2D matrix

     (defvar m (make-array (list r c) :initial-contents '((...) ...))

and that I have a "row" displaced into it.

     (defvar row (make-array c :displaced-to m :displaced-index-offset
0))

Now I want to get the second row.  Ooops.  AFAIU I cannot do

     (setf (array-displaced-index-offset row) (+ (nth-value 1 (array-
displacement row)) c))

How do people do this?  (Note.  You cannot re-allocate ROW.  And
ADJUST-ARRAY does not seem to allow this).

Cheers
--
Marco

From: Marco Antoniotti
Subject: Re: Changing the :DISPLACED-INDEX-OFFSET of a displaced array
Date: 
Message-ID: <dc7dd2a7-94df-4398-a63b-058677bf1b97@m36g2000hse.googlegroups.com>
On Mar 17, 11:05 am, Marco Antoniotti <·······@gmail.com> wrote:
> Hi
>
> suppose I have a 2D matrix
>
>      (defvar m (make-array (list r c) :initial-contents '((...) ...))
>
> and that I have a "row" displaced into it.
>
>      (defvar row (make-array c :displaced-to m :displaced-index-offset
> 0))
>
> Now I want to get the second row.  Ooops.  AFAIU I cannot do
>
>      (setf (array-displaced-index-offset row) (+ (nth-value 1 (array-
> displacement row)) c))
>
> How do people do this?  (Note.  You cannot re-allocate ROW.  And
> ADJUST-ARRAY does not seem to allow this).
>

Just to prevent some comments: I know about the Lisp Machines array
facilities and I did do a cursory check of previous posts.

Cheers
--
Marco
From: Pascal J. Bourguignon
Subject: Re: Changing the :DISPLACED-INDEX-OFFSET of a displaced array
Date: 
Message-ID: <7ciqzlr616.fsf@pbourguignon.anevia.com>
Marco Antoniotti <·······@gmail.com> writes:

> Hi
>
> suppose I have a 2D matrix
>
>      (defvar m (make-array (list r c) :initial-contents '((...) ...))
>
> and that I have a "row" displaced into it.
>
>      (defvar row (make-array c :displaced-to m :displaced-index-offset
> 0))
>
> Now I want to get the second row.  Ooops.  AFAIU I cannot do
>
>      (setf (array-displaced-index-offset row) (+ (nth-value 1 (array-
> displacement row)) c))
>
> How do people do this?  (Note.  You cannot re-allocate ROW.  And
> ADJUST-ARRAY does not seem to allow this).

Yes, ADJUST-ARRAY does allow it.

    (setf row  (adjust-array row (array-dimensions row)
                             :element-type (array-element-type row)
                             :displaced-to (array-displacement row)
                             :displaced-index-offset (+ (array-dimension (array-displacement row) 1)
                                                        (nth-value 1 (array-displacement row)))))

If you want to ensure that (EQ row previous-row), you should ensure that row is adjustable:

    (setf row (make-array c :displaced-to m :displaced-index-offset 0 :adjustable t))

-- 
__Pascal Bourguignon__
From: Marco Antoniotti
Subject: Re: Changing the :DISPLACED-INDEX-OFFSET of a displaced array
Date: 
Message-ID: <f7cbd137-51cc-4749-829c-bfdca3951050@n58g2000hsf.googlegroups.com>
On Mar 17, 11:36 am, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> Marco Antoniotti <·······@gmail.com> writes:
> > Hi
>
> > suppose I have a 2D matrix
>
> >      (defvar m (make-array (list r c) :initial-contents '((...) ...))
>
> > and that I have a "row" displaced into it.
>
> >      (defvar row (make-array c :displaced-to m :displaced-index-offset
> > 0))
>
> > Now I want to get the second row.  Ooops.  AFAIU I cannot do
>
> >      (setf (array-displaced-index-offset row) (+ (nth-value 1 (array-
> > displacement row)) c))
>
> > How do people do this?  (Note.  You cannot re-allocate ROW.  And
> > ADJUST-ARRAY does not seem to allow this).
>
> Yes, ADJUST-ARRAY does allow it.
>
>     (setf row  (adjust-array row (array-dimensions row)
>                              :element-type (array-element-type row)
>                              :displaced-to (array-displacement row)
>                              :displaced-index-offset (+ (array-dimension (array-displacement row) 1)
>                                                         (nth-value 1 (array-displacement row)))))
>
> If you want to ensure that (EQ row previous-row), you should ensure that row is adjustable:
>
>     (setf row (make-array c :displaced-to m :displaced-index-offset 0 :adjustable t))
>

Thanks.  I think I got confused by the use of the :displaced-
to/:adjustable combination in ADJUST-ARRAY.  Do you think that it'd be
warranted to assume that this idiom does not cons?

Cheers
--
Marco
From: Pascal J. Bourguignon
Subject: Re: Changing the :DISPLACED-INDEX-OFFSET of a displaced array
Date: 
Message-ID: <7ceja9r15a.fsf@pbourguignon.anevia.com>
Marco Antoniotti <·······@gmail.com> writes:

> On Mar 17, 11:36�am, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> Marco Antoniotti <·······@gmail.com> writes:
>> > Hi
>>
>> > suppose I have a 2D matrix
>>
>> > � � �(defvar m (make-array (list r c) :initial-contents '((...) ...))
>>
>> > and that I have a "row" displaced into it.
>>
>> > � � �(defvar row (make-array c :displaced-to m :displaced-index-offset
>> > 0))
>>
>> > Now I want to get the second row. �Ooops. �AFAIU I cannot do
>>
>> > � � �(setf (array-displaced-index-offset row) (+ (nth-value 1 (array-
>> > displacement row)) c))
>>
>> > How do people do this? �(Note. �You cannot re-allocate ROW. �And
>> > ADJUST-ARRAY does not seem to allow this).
>>
>> Yes, ADJUST-ARRAY does allow it.
>>
>> � � (setf row �(adjust-array row (array-dimensions row)
>> � � � � � � � � � � � � � � �:element-type (array-element-type row)
>> � � � � � � � � � � � � � � �:displaced-to (array-displacement row)
>> � � � � � � � � � � � � � � �:displaced-index-offset (+ (array-dimension (array-displacement row) 1)
>> � � � � � � � � � � � � � � � � � � � � � � � � � � � � (nth-value 1 (array-displacement row)))))
>>
>> If you want to ensure that (EQ row previous-row), you should ensure that row is adjustable:
>>
>> � � (setf row (make-array c :displaced-to m :displaced-index-offset 0 :adjustable t))
>>
>
> Thanks.  I think I got confused by the use of the :displaced-
> to/:adjustable combination in ADJUST-ARRAY.  Do you think that it'd be
> warranted to assume that this idiom does not cons?

Yes, clhs adjust-array says:

     If adjust-array is applied to an array that is actually
     adjustable, the array returned is identical to array.

Also, while it's not clearly specified that the array returned by
adjust-array must be adjustable, the Example seems to indicate so, and
I'd expect so too, so even if you didn't create an adjustable array to
begin with, on the second iteration, you should get (with a sane
implementation) an adjustable array, or, said otherwise, you won't
allocate more than two rows.

-- 
__Pascal Bourguignon__
From: Marco Antoniotti
Subject: Re: Changing the :DISPLACED-INDEX-OFFSET of a displaced array
Date: 
Message-ID: <18a38ab6-aebc-4766-af22-aec94b264e8b@d21g2000prf.googlegroups.com>
On Mar 17, 1:22 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> Marco Antoniotti <·······@gmail.com> writes:
> > On Mar 17, 11:36 am, ····@informatimago.com (Pascal J. Bourguignon)
> > wrote:
> >> Marco Antoniotti <·······@gmail.com> writes:
> >> > Hi
>
> >> > suppose I have a 2D matrix
>
> >> >      (defvar m (make-array (list r c) :initial-contents '((...) ...))
>
> >> > and that I have a "row" displaced into it.
>
> >> >      (defvar row (make-array c :displaced-to m :displaced-index-offset
> >> > 0))
>
> >> > Now I want to get the second row.  Ooops.  AFAIU I cannot do
>
> >> >      (setf (array-displaced-index-offset row) (+ (nth-value 1 (array-
> >> > displacement row)) c))
>
> >> > How do people do this?  (Note.  You cannot re-allocate ROW.  And
> >> > ADJUST-ARRAY does not seem to allow this).
>
> >> Yes, ADJUST-ARRAY does allow it.
>
> >>     (setf row  (adjust-array row (array-dimensions row)
> >>                              :element-type (array-element-type row)
> >>                              :displaced-to (array-displacement row)
> >>                              :displaced-index-offset (+ (array-dimension (array-displacement row) 1)
> >>                                                         (nth-value 1 (array-displacement row)))))
>
> >> If you want to ensure that (EQ row previous-row), you should ensure that row is adjustable:
>
> >>     (setf row (make-array c :displaced-to m :displaced-index-offset 0 :adjustable t))
>
> > Thanks.  I think I got confused by the use of the :displaced-
> > to/:adjustable combination in ADJUST-ARRAY.  Do you think that it'd be
> > warranted to assume that this idiom does not cons?
>
> Yes, clhs adjust-array says:
>
>      If adjust-array is applied to an array that is actually
>      adjustable, the array returned is identical to array.
>
> Also, while it's not clearly specified that the array returned by
> adjust-array must be adjustable, the Example seems to indicate so, and
> I'd expect so too, so even if you didn't create an adjustable array to
> begin with, on the second iteration, you should get (with a sane
> implementation) an adjustable array, or, said otherwise, you won't
> allocate more than two rows.
>

Yep.  I'd agree.  Still using ADJUST-ARRAY to get what is essentially
a move in the offset seems quite an overkill.  Oh well.

Cheers
--
Marco
From: Pascal J. Bourguignon
Subject: Re: Changing the :DISPLACED-INDEX-OFFSET of a displaced array
Date: 
Message-ID: <7clk4hpfyf.fsf@pbourguignon.anevia.com>
Marco Antoniotti <·······@gmail.com> writes:

> On Mar 17, 1:22�pm, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> Marco Antoniotti <·······@gmail.com> writes:
>> > On Mar 17, 11:36�am, ····@informatimago.com (Pascal J. Bourguignon)
>> > wrote:
>> >> Marco Antoniotti <·······@gmail.com> writes:
>> >> > Hi
>>
>> >> > suppose I have a 2D matrix
>>
>> >> > � � �(defvar m (make-array (list r c) :initial-contents '((...) ...))
>>
>> >> > and that I have a "row" displaced into it.
>>
>> >> > � � �(defvar row (make-array c :displaced-to m :displaced-index-offset
>> >> > 0))
>>
>> >> > Now I want to get the second row. �Ooops. �AFAIU I cannot do
>>
>> >> > � � �(setf (array-displaced-index-offset row) (+ (nth-value 1 (array-
>> >> > displacement row)) c))
>>
>> >> > How do people do this? �(Note. �You cannot re-allocate ROW. �And
>> >> > ADJUST-ARRAY does not seem to allow this).
>>
>> >> Yes, ADJUST-ARRAY does allow it.
>>
>> >> � � (setf row �(adjust-array row (array-dimensions row)
>> >> � � � � � � � � � � � � � � �:element-type (array-element-type row)
>> >> � � � � � � � � � � � � � � �:displaced-to (array-displacement row)
>> >> � � � � � � � � � � � � � � �:displaced-index-offset (+ (array-dimension (array-displacement row) 1)
>> >> � � � � � � � � � � � � � � � � � � � � � � � � � � � � (nth-value 1 (array-displacement row)))))
>>
>> >> If you want to ensure that (EQ row previous-row), you should ensure that row is adjustable:
>>
>> >> � � (setf row (make-array c :displaced-to m :displaced-index-offset 0 :adjustable t))
>>
>> > Thanks. �I think I got confused by the use of the :displaced-
>> > to/:adjustable combination in ADJUST-ARRAY. �Do you think that it'd be
>> > warranted to assume that this idiom does not cons?
>>
>> Yes, clhs adjust-array says:
>>
>> � � �If adjust-array is applied to an array that is actually
>> � � �adjustable, the array returned is identical to array.
>>
>> Also, while it's not clearly specified that the array returned by
>> adjust-array must be adjustable, the Example seems to indicate so, and
>> I'd expect so too, so even if you didn't create an adjustable array to
>> begin with, on the second iteration, you should get (with a sane
>> implementation) an adjustable array, or, said otherwise, you won't
>> allocate more than two rows.
>>
>
> Yep.  I'd agree.  Still using ADJUST-ARRAY to get what is essentially
> a move in the offset seems quite an overkill.  Oh well.

Well implemented, adjust-array won't do much more than a few tests,
and set the new offset.

On a nice implementation, not passing superfluous arguments may allow
it to open-code an optimized version of adjust-array that would just
check the bounds and set the new index:

   (setf row (adjust-array row (array-dimensions row)
                :displaced-index-offset (+ (array-dimension (array-displacement row) 1)
                              (nth-value 1 (array-displacement row)))))


-- 
__Pascal Bourguignon__
From: Richard M Kreuter
Subject: Re: Changing the :DISPLACED-INDEX-OFFSET of a displaced array
Date: 
Message-ID: <87wso1z58s.fsf@progn.net>
···@informatimago.com (Pascal J. Bourguignon) writes:
> Marco Antoniotti <·······@gmail.com> writes:
>
>>>> How do people do this? (Note. You cannot re-allocate ROW. And
>>>> ADJUST-ARRAY does not seem to allow this).
>>>
>>> Yes, ADJUST-ARRAY does allow it.
>>
>> Thanks.  I think I got confused by the use of the :displaced-
>> to/:adjustable combination in ADJUST-ARRAY.  Do you think that it'd be
>> warranted to assume that this idiom does not cons?
>
> Yes, clhs adjust-array says:
>
>      If adjust-array is applied to an array that is actually
>      adjustable, the array returned is identical to array.
>
> Also, while it's not clearly specified that the array returned by
> adjust-array must be adjustable, the Example seems to indicate so, and
> I'd expect so too, so even if you didn't create an adjustable array to
> begin with, on the second iteration, you should get (with a sane
> implementation) an adjustable array, or, said otherwise, you won't
> allocate more than two rows.

On the other hand, using ADJUST-ARRAY to change a displaced array's
offset does require 2 or 3 keyword/argument pairs, and so on some
implementations the call will heap allocate the &REST list.

(Additionally, and probably more importantly, some implementations
aren't very aggressive at optimizing displaced array access, and so
any memory savings from using a displaced array will cost some speed.
Anecdotally, I've found that on implementations with generational
garbage collectors, in some programs where it would seem that a
displaced array might be a win, allocating a fresh array and letting
it become garbage can be competitive with using a displaced array; the
canonical case would be one where the subarray is only briefly
interesting, and not too much additional garbage gets allocated while
using the subarray.  But of course if you're relying on a destructive
modification to one array being visibile in the other, this isn't an
option.  Probably you'd have to test the program on the implementation
to find out what wins, and maybe factor out the choice of whether to
displace or to copy so that you can switch back and forth as the
program evolves.)

--
RmK