newMat and shallow copy

jocaps
Messages : 118
Inscription : lun. avr. 17, 2017 4:32 pm

newMat and shallow copy

Message par jocaps » ven. déc. 01, 2017 8:39 am

Hi,

I am not sure if I should report this as a bug or if it is my misunderstanding. Throughout I am using giacpy 0.6.1

Consider the following code:

Code : Tout sélectionner

from giacpy import newMat
mat = newMat(2,2)
mat[1,1]=2
The result is a (duplicate of) 2 on all of the entries of the second column of the matrix i.e. we get the output [[0,2],[0,2]]. Of course what I/we want is [[0,2],[0,0]]

It seems that newMat does a shallow copy of [0,0]. This is similar to the following simple python command (which has the same problem because python does a shallow copy of the vectors:

Code : Tout sélectionner

mat = 2*[[0,0]]
mat[1][1] =2
declaring the matrix directly instead of using newMat will not have this problem (vectors are nor referenced to each other!) and have the desired effect:

Code : Tout sélectionner

from giacpy import giac
mat = giac([[0,0],[0,0]])
mat[1,1]=2

frederic han
Messages : 1113
Inscription : dim. mai 20, 2007 7:09 am
Localisation : Paris
Contact :

Re: newMat and shallow copy

Message par frederic han » ven. déc. 01, 2017 9:52 am

indeed I have used in giacpy the same behaviour as python lists to be more efficient, while in giac/xcas the default affectation is := and recopy everything.

The problem is the same in giac/xcas with newMat so it should be changed there.

Code : Tout sélectionner

2>> A:=newMat(2,2)
[[0,0],[0,0]]
// Time 0
3>> A
[[0,0],[0,0]]
// Time 0
4>> A[1,1]=<2
[[0,2],[0,2]]


but as it is,
you have to find any trick to force different vectors. the following 2 seems to work but the first one looks faster:

Code : Tout sélectionner

from giacpy import matrix,NewList
In [84]: time n=1000;A=matrix(n,n,newList(n**2))
CPU times: user 77.3 ms, sys: 6.32 ms, total: 83.6 ms
Wall time: 75.9 ms
// Success

In [85]: time n=1000;A=matrix(n,n,'(u,v)->0')

Evaluation time: 1.15
CPU times: user 1.14 s, sys: 9.56 ms, total: 1.15 s
Wall time: 1.13 s

jocaps
Messages : 118
Inscription : lun. avr. 17, 2017 4:32 pm

Re: newMat and shallow copy

Message par jocaps » ven. déc. 01, 2017 10:13 am

I don't know what the source code is in giac/giacpy that makes newMat. For python, simply writing

Code : Tout sélectionner

mat = [[0 for c in xrange(coldim)] for r in xrange(rowdim)]
should be fast. I think loops are very fast in both python and C/C++ (unless there is very few things to do in the loop for which you need to unroll).

For the moment I use idn (identitty matrix) which does not suffer from this behaviour. Since I have a square matrix and I know I am going to change all the entries of the martrix I am not worried of using it. How does the identity matrix creating differ in giacpy? is it as fast as newMat (if so, maybe you can use a similar code for the implementation of newMat).

Code : Tout sélectionner

from giacpy import idn
mat=idn(4)
mat[1,1]=2

frederic han
Messages : 1113
Inscription : dim. mai 20, 2007 7:09 am
Localisation : Paris
Contact :

Re: newMat and shallow copy

Message par frederic han » ven. déc. 01, 2017 10:38 am

jocaps a écrit :I don't know what the source code is in giac/giacpy that makes newMat. For python, simply writing

Code : Tout sélectionner

mat = [[0 for c in xrange(coldim)] for r in xrange(rowdim)]
should be fast. I think loops are very fast in both python and C/C++ (unless there is very few things to do in the loop for which you need to unroll).

For the moment I use idn (identitty matrix) which does not suffer from this behaviour. Since I have a square matrix and I know I am going to change all the entries of the martrix I am not worried of using it. How does the identity matrix creating differ in giacpy? is it as fast as newMat (if so, maybe you can use a similar code for the implementation of newMat).

Code : Tout sélectionner

from giacpy import idn
mat=idn(4)
mat[1,1]=2

Bernard will change newMat in the next giac version, so I will update the giac.dll (cf http://xcas.e.ujf-grenoble.fr/XCAS/view ... f=4&t=1955)

So up to now the following 2 are similar and will also solve your problem.

Code : Tout sélectionner

from giacpy import idn,matrix,newList
n=1000
A=0*idn(n)
B=matrix(n,n,newList(n**2))

Répondre