naming mxAlgebra objects automatically

4 replies [Last post]
Janosch's picture
Offline
Joined: 05/10/2010

Hello everyone,
i am trying to generate a model with several mxAlgebra objects in it. The thing is that they all have the same structure (except for one value), but must be assigned different names. Right now I'm specifying them seperately, so:

mxAlgebra(EVEC%*%(exp(1%x%EVA)-tempa)%*%solve(EVEC), name = "EXPd1"),
mxAlgebra(EVEC%*%(exp(2%x%EVA)-tempa)%*%solve(EVEC), name = "EXPd2"),
mxAlgebra(EVEC%*%(exp(3%x%EVA)-tempa)%*%solve(EVEC), name = "EXPd3"),
mxAlgebra(EVEC%*%(exp(4%x%EVA)-tempa)%*%solve(EVEC), name = "EXPd4"),
mxAlgebra(EVEC%*%(exp(5%x%EVA)-tempa)%*%solve(EVEC), name = "EXPd5"),

Where the only difference between the algebras is the number in the "exp()". I thought that I could create a vector with those numbers in it and loop through that vector, while giving the mxAlgebra a different name on every iteration. The point is that I want my syntax to work no matter how many different "EXPd's" I have, without having to specify them manually (it could eventually be up to a hundred so that would be a lot of work). I thought of something like:

numbers=c(1,2,3,4,5)

for (i in 1:5){
mxAlgebra(EVEC%*%(exp(numbers[i]%x%EVA)-tempa)%*%solve(EVEC), name = paste("EXPd",i,sep=""))

},

However that doesnt work... openmx doesnt seem to recognize the mxAlgebras.
Does anyone have an idea of how I could get this going? I thought of creating an object in R, so outside of openmx, with the mxAlgebra statements in it and reffering to the specific points in that object in my model specifications. But i couldnt get that going as well.

I'll be glad for any kind of suggestions!

Greetings

Jan

mspiegel's picture
Offline
Joined: 07/31/2009
Excellent question! The

Excellent question! The expression you have written almost works. I would use something like:

numbers <- c(1,2,3,4,5)
generateAlgebra <- function(number) {
&nbsp;&nbsp;eval(substitute(mxAlgebra(EVEC %*% (exp(replace %x% EVA) - tempa) 
&nbsp;&nbsp;&nbsp;&nbsp;%*% solve(EVEC), name = paste("EXPd", replace, sep="")), 
&nbsp;&nbsp;&nbsp;&nbsp;list(replace = number)))
}
algebras <- lapply(numbers, generateAlgebra)
model <- mxModel(model, algebras)

Also, OpenMx does not yet perform common subexpression elimination. So you probably want to move solve(EVEC) into a new algebra, and then reference that algebra from EXPd1-5.

Janosch's picture
Offline
Joined: 05/10/2010
Aah, maybe i was a bit to

Aah, maybe i was a bit to enthusiastic. I didn't post my question carefully. The problem is that the 'numbers' values that have to be in the calculation are not necessarily the same as the names of the mxAlgebras. So while the mxAlgebras should indeed be named "EXPd1", "EXPd2" etc., the values in the 'numbers' vector should possibly be any value. So e.g.: numbers = c(.5,.3,.6,.1,.2).
I don't see right now how to implement that in your function, since 'lapply' calls on the same vector. And since openmx won't accept names with a '.' in it, I also can't use the given 'numbers' values as names...

Do you have a suggestion how to solve that?

Greetings

mspiegel's picture
Offline
Joined: 07/31/2009
No problem. We can bring out

No problem. We can bring out the bigger guns and use 'mapply' instead of 'lapply':

numbers <- c(1, 2, 3, 4, 5)
values <- c(0.5, 0.3, 0.6, 0.1, 0.2)
generateAlgebra <- function(number, value) {
&nbsp;&nbsp;eval(substitute(mxAlgebra(EVEC %*% (exp(replace2 %x% EVA) - tempa)
&nbsp;&nbsp;&nbsp;&nbsp;%*% solve(EVEC), name = paste("EXPd", replace1, sep="")),
&nbsp;&nbsp;&nbsp;&nbsp;list(replace1 = number, replace2 = value)))
}
algebras <- mapply(generateAlgebra, numbers, values)

There's probably a way to do this using only lapply, but the mapply approach is the first that came to mind.

Janosch's picture
Offline
Joined: 05/10/2010
Well thanks a lot for that!

Well thanks a lot for that! It really seems to work now.
And i think it would have taken me some years to figure that out by myself :)