Function variables declared as global! Why?

Messages in english

Modérateur : xcasadmin

alexg
Messages : 11
Inscription : lun. janv. 24, 2011 9:56 pm

Function variables declared as global! Why?

Message par alexg » sam. mars 31, 2012 2:16 pm

I discovered this trying to write a function that processes each element of a matrix.
It seems that if there is any level of complexity in the function, the arguments are treated as globals!
I am not sure, but I think this may even be related to the problem of currying which I mentioned in the giac forum.
In any case I would welcome opinions.

Suppose I have a matrix and I want to generate another matrix, where every element is, say, the sin() of the original.
I thought I would use makemat/3 taking advantage of its built-in properties, rather than loop through the whole matrix.
Here's on version of it, it tried some other versions too, but they all behave about the same.

Code : Tout sélectionner

mat_func(m_1,f_1):= {
local j,k,
matfunc1 := (j,k) -> (f_1(m_1[j][k])); 
makemat(matfunc1,nrows(m_1),ncols(m_1));
}
This compiles, but with the following warnings!

Code : Tout sélectionner

// Warning: f_1,m_1, declared as global variable(s)
// Parsing mat_func
// Success compiling mat_func

======

(m_1,f_1)-> 
{ local j,k,(matfunc1:= (j,k)->f_1((m_1[j])[k])); 
  makemat(matfunc1,nrows(m_1),ncols(m_1));  
}
Any ideas?

I also want to add that this way of writing the function is very inefficient, the following code taking just over 1 second for a 100x100 matrix, 15 seconds for a 200x200, 80 seconds for a 300x300, 260 for a 400x400 and 592 for a 500x500!
That would suggest a time of O(n^4) instead of O(n^2).
Ouch! So much for using the builtin...

Code : Tout sélectionner

m1:=randmatrix( 500,500,'randnorm(0,1)');
n11:=mat_func(m1,sin);
Thanks

parisse
Messages : 5739
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: Function variables declared as global! Why?

Message par parisse » sam. mars 31, 2012 5:09 pm

Ok, it's in O(n^4) because for each call of the f_1 function, m_1 has been replaced by it's value and is therefore evaled as a matrix (and not as an identifier), which is an O(n^2) process.
It seems you can avoid this by quoting m1 in matfunc

Code : Tout sélectionner

mat_func(m_1,f_1):= {
local j,k,
matfunc1 := (j,k) -> (f_1('m_1'[j][k]));
makemat(matfunc1,nrows(m_1),ncols(m_1));
}

alexg
Messages : 11
Inscription : lun. janv. 24, 2011 9:56 pm

Re: Function variables declared as global! Why?

Message par alexg » sam. mars 31, 2012 9:51 pm

Yes, that solution is perfect! 1.8" for a 500^2 matrix instead of 600".
Thank you so much.

I don't suppose you have any ideas on the "global variable" warning for the function parameters?

alexg
Messages : 11
Inscription : lun. janv. 24, 2011 9:56 pm

Re: Function variables declared as global! Why?

Message par alexg » sam. mars 31, 2012 10:14 pm

Hm, actually, just using apply(fn,mtx) or map(mtx,fn) is much quicker.
Very useful, I hadn't noticed it before...

Répondre