From: Vladimir Zolotykh
Subject: copy-array
Date: 
Message-ID: <3D1DD355.7019B22C@eurocom.od.ua>
What is the known most concise way to copy an
arbitrary array I wonder.

For now I had only seen something

(let ((new-array (make-array (array-dimensions old-array)
                             :element-type (array-element-type old-array)
  ;; Some sort of LOOPs here to copy contents
  )

I have no bright idea how to copy array's contents,
not saying about fill-pointer, displacement etc.

For now I'd satisfied with dimensions, type and contents
and leave others to some future time. 

-- 
Vladimir Zolotykh

From: Kalle Olavi Niemitalo
Subject: Re: copy-array
Date: 
Message-ID: <878z4y10r9.fsf@Astalo.y2000.kon.iki.fi>
Vladimir Zolotykh <······@eurocom.od.ua> writes:

>   ;; Some sort of LOOPs here to copy contents

If you use ROW-MAJOR-AREF and ARRAY-TOTAL-SIZE, you need only one loop.
From: Louis Theran
Subject: Re: copy-array
Date: 
Message-ID: <a2503e25.0206291506.9db884f@posting.google.com>
Kalle Olavi Niemitalo <···@iki.fi> wrote in message news:<··············@Astalo.y2000.kon.iki.fi>...
> Vladimir Zolotykh <······@eurocom.od.ua> writes:
> 
> >   ;; Some sort of LOOPs here to copy contents
> 
> If you use ROW-MAJOR-AREF and ARRAY-TOTAL-SIZE, you need only one loop.

You can get away with no loops like this:

  (defun linearize-array (array)
    (make-array (array-total-size array) :displaced-to array))

  (defun copy-array (array)
    (let ((storage (copy-seq (linearize-array array))))
      (make-array (array-dimensions array) :displaced-to storage)))


^L
From: Vladimir Zolotykh
Subject: Re: copy-array
Date: 
Message-ID: <3D1EEC73.CF154C05@eurocom.od.ua>
Very nice!

BTW the following code I have found in C.L.L archives
posted some time ago by Barry Margolin if I am not mistaken.
Could you tell me why it might not work in ACL61 ?
Should it work in compliant CL I wonder ?
It works in CMUCL18c for example.

(defun copy-array (array)
  (let ((new (make-array (array-dimensions array) :displaced-to array)))
    (adjust-array new (array-dimensions array) :displayced-to nil)))


Louis Theran wrote:
> 
> Kalle Olavi Niemitalo <···@iki.fi> wrote in message news:<··············@Astalo.y2000.kon.iki.fi>...
> > Vladimir Zolotykh <······@eurocom.od.ua> writes:
> >
> > >   ;; Some sort of LOOPs here to copy contents
> >
> > If you use ROW-MAJOR-AREF and ARRAY-TOTAL-SIZE, you need only one loop.
> 
> You can get away with no loops like this:
> 
>   (defun linearize-array (array)
>     (make-array (array-total-size array) :displaced-to array))
> 
>   (defun copy-array (array)
>     (let ((storage (copy-seq (linearize-array array))))
>       (make-array (array-dimensions array) :displaced-to storage)))
> 
> ^L

-- 
Vladimir Zolotykh
From: Kimmo T Takkunen
Subject: Re: copy-array
Date: 
Message-ID: <slrnahso1f.7l0.ktakkune@sirppi.helsinki.fi>
In article <·················@eurocom.od.ua>, Vladimir Zolotykh wrote:
> What is the known most concise way to copy an
> arbitrary array I wonder.
> 
> For now I had only seen something
> 
> (let ((new-array (make-array (array-dimensions old-array)
>                              :element-type (array-element-type old-array)
>   ;; Some sort of LOOPs here to copy contents
>   )
> 
> I have no bright idea how to copy array's contents,
> not saying about fill-pointer, displacement etc.

I just wrote this. I may have made errors. Corrections welcome.

;;; Trying to make exact copy of an array. 
(defun copy-array (old-array)
  "Copy array." ;<- Better docstring is left as an exercise for the reader 
  (check-type old-array array)
  (multiple-value-bind (displaced-to displaced-index-offset)
      (array-displacement old-array)
    ;; initial-contents must not be supplied if displaced-to is supplied.
    (if displaced-to
        ;; displaced array
        (make-array (array-dimensions old-array)
                    :element-type (array-element-type old-array)
                    :adjustable (adjustable-array-p old-array)
                    :fill-pointer (if (array-has-fill-pointer-p old-array)
                                      (fill-pointer old-array)
                                    nil)
                    :displaced-to displaced-to
                    :displaced-index-offset displaced-index-offset)
      ;; array with initial contents
      (make-array (array-dimensions old-array)
                  :element-type (array-element-type old-array)
                  :initial-contents old-array
                  :adjustable (adjustable-array-p old-array)
                  :fill-pointer (if (array-has-fill-pointer-p old-array)
                                    (fill-pointer old-array)
                                  nil)))))

--  Kimmo,  http://www.iki.fi/kt/
((lambda (integer) 
   (coerce (loop for i upfrom 0 by 8 below (integer-length integer)
                 collect (code-char (ldb (byte 8 i) integer))) 'string))
 100291759904362517251920937783274743691485481194069255743433035)
From: Vladimir Zolotykh
Subject: Re: copy-array
Date: 
Message-ID: <3D1EC183.35A2FDA0@eurocom.od.ua>
Kimmo T Takkunen wrote:
> 
> In article <·················@eurocom.od.ua>, Vladimir Zolotykh wrote:
> > What is the known most concise way to copy an
> > arbitrary array I wonder.
> >
> > For now I had only seen something
> >
> > (let ((new-array (make-array (array-dimensions old-array)
> >                              :element-type (array-element-type old-array)
> >   ;; Some sort of LOOPs here to copy contents
> >   )
> >
> > I have no bright idea how to copy array's contents,
> > not saying about fill-pointer, displacement etc.
> 
> I just wrote this. I may have made errors. Corrections welcome.
> 
> ;;; Trying to make exact copy of an array.
> (defun copy-array (old-array)
>   "Copy array." ;<- Better docstring is left as an exercise for the reader
>   (check-type old-array array)
>   (multiple-value-bind (displaced-to displaced-index-offset)
>       (array-displacement old-array)
>     ;; initial-contents must not be supplied if displaced-to is supplied.
>     (if displaced-to
>         ;; displaced array
>         (make-array (array-dimensions old-array)
>                     :element-type (array-element-type old-array)
>                     :adjustable (adjustable-array-p old-array)
>                     :fill-pointer (if (array-has-fill-pointer-p old-array)
>                                       (fill-pointer old-array)
>                                     nil)
>                     :displaced-to displaced-to
>                     :displaced-index-offset displaced-index-offset)
>       ;; array with initial contents
>       (make-array (array-dimensions old-array)
>                   :element-type (array-element-type old-array)
>                   :initial-contents old-array

Which CL implementation you are using ? Does it support array
as value for :initial-contents ?

>                   :adjustable (adjustable-array-p old-array)
>                   :fill-pointer (if (array-has-fill-pointer-p old-array)
>                                     (fill-pointer old-array)
>                                   nil)))))
> 
> --  Kimmo,  http://www.iki.fi/kt/
> ((lambda (integer)
>    (coerce (loop for i upfrom 0 by 8 below (integer-length integer)
>                  collect (code-char (ldb (byte 8 i) integer))) 'string))
>  100291759904362517251920937783274743691485481194069255743433035)

-- 
Vladimir Zolotykh
From: Kimmo T Takkunen
Subject: Re: copy-array
Date: 
Message-ID: <slrnahtl6l.nec.ktakkune@sirppi.helsinki.fi>
In article <·················@eurocom.od.ua>, Vladimir Zolotykh wrote:
> Kimmo T Takkunen wrote:
>> 
>> In article <·················@eurocom.od.ua>, Vladimir Zolotykh wrote:
>> > What is the known most concise way to copy an
>> > arbitrary array I wonder.
>> >
>> > For now I had only seen something
>> >
>> > (let ((new-array (make-array (array-dimensions old-array)
>> >                              :element-type (array-element-type old-array)
>> >   ;; Some sort of LOOPs here to copy contents
>> >   )
>> >
>> > I have no bright idea how to copy array's contents,
>> > not saying about fill-pointer, displacement etc.
>> 

>>       ;; array with initial contents
>>       (make-array (array-dimensions old-array)
>>                   :element-type (array-element-type old-array)
>>                   :initial-contents old-array

Heh. It seems I had blind spot in my thinking.
It was so intuitively evident to me that initial-contents takes array values
that I didn't even understand your question. 

> Which CL implementation you are using ? Does it support array
> as value for :initial-contents ?

No. It's a bug. Function was wrongly named. Should have been
copy-vector.  When I made this function, I wanted copy-vector and it
worked. Then I just over-generalized.

;;; Sigh. Next version.

(defun copy-array-elements (from to)
  (loop for i below (array-total-size from)
	do (setf (row-major-aref to i) (row-major-aref from i))
	finally (return to)))

(defun copy-array (old-array)
  "Make exact copy of array."
  (check-type old-array array)
  (multiple-value-bind (displaced-to displaced-index-offset)
      (array-displacement old-array)
    ;; initial-contents must not be supplied if displaced-to is supplied.
    (if displaced-to
        ;; displaced array
        (make-array (array-dimensions old-array)
                    :element-type (array-element-type old-array)
                    :adjustable (adjustable-array-p old-array)
                    :fill-pointer (if (array-has-fill-pointer-p old-array)
                                      (fill-pointer old-array)
                                    nil)
                    :displaced-to displaced-to
                    :displaced-index-offset displaced-index-offset)
      ;; array with initial contents
      (copy-array-elements old-array
	(make-array (array-dimensions old-array)
		    :element-type (array-element-type old-array)
		    :adjustable (adjustable-array-p old-array)
		    :fill-pointer (if (array-has-fill-pointer-p old-array)
				      (fill-pointer old-array)
				    nil))))))

 
--  Kimmo,  http://www.iki.fi/kt/
((lambda (integer) 
   (coerce (loop for i upfrom 0 by 8 below (integer-length integer)
                 collect (code-char (ldb (byte 8 i) integer))) 'string))
 100291759904362517251920937783274743691485481194069255743433035)
From: Kalle Olavi Niemitalo
Subject: Re: copy-array
Date: 
Message-ID: <87u1nlqhj5.fsf@Astalo.y2000.kon.iki.fi>
········@cc.helsinki.fi (Kimmo T Takkunen) writes:

>       (make-array (array-dimensions old-array)
>                   :element-type (array-element-type old-array)
>                   :initial-contents old-array

The initial-contents must be a nested structure of sequences, so
this works only with one-dimensional arrays.  That is, the
initial-contents of a 2*2 array could be ((1 2) (3 4)), #(#(1 2)
#(3 4)) or a mix like ((1 2) #(3 4)), but not #2A((1 2) (3 4)).