Constraining results of an algebra

Posted on
No user picture. szellers Joined: 04/04/2018
Hi!

I am trying to constrain the results of an algebra, either to a fixed value or constraining the results of two algebras to be equivalent. I am using https://openmx.ssri.psu.edu//wiki/mxConstraint-help as a starting point.

Example output is attached, but the relevant lines of code are below

I want to fix AlCO[2,2] to 0 in the first example.


nl <- 3 # number of latent factors
# Matrices ac, cc, and ec to store a, c, and e path coefficients for latent phenotype(s)
XMN <- mxMatrix(type="Lower", nrow=nl, ncol=nl, free=TRUE,
values=c(.6,
.1, .1,
.1, .1, 0),
labels=c("x11MN",
"x21MN", "x22MN",
"x31MN", "x32MN", "x33MN"), name="XMN" )

YMN <- mxMatrix(type="Lower", nrow=nl, ncol=nl, free=TRUE,
values=c(.6,
.1, .1,
.1, .1, .1),
labels=c("y11MN",
"y21MN", "y22MN",
"y31MN", "y32MN", "y33MN"), name="YMN" )

ZMN <- mxMatrix(type="Lower", nrow=nl, ncol=nl, free=TRUE,
values=c(.6,
.1, .1,
.1, .1, .1),
labels=c("z11MN",
"z21MN", "z22MN",
"z31MN", "z32MN", "z33MN"), name="ZMN" )

XCO <- mxMatrix(type="Lower", nrow=nl, ncol=nl, free=TRUE,
values=c(.6,
.1, .1,
.1, .1, 0),
labels=c("x11CO",
"x21CO", "x22CO",
"x31CO", "x32CO", "x33CO"), name="XCO" )

YCO <- mxMatrix(type="Lower", nrow=nl, ncol=nl, free=TRUE,
values=c(.6,
.1, .1,
.1, .1, .1),
labels=c("y11CO",
"y21CO", "y22CO",
"y31CO", "y32CO", "y33CO"), name="YCO" )

ZCO <- mxMatrix(type="Lower", nrow=nl, ncol=nl, free=TRUE,
values=c(.6,
.1, .1,
.1, .1, .1),
labels=c("z11CO",
"z21CO", "z22CO",
"z31CO", "z32CO", "z33CO"), name="ZCO" )

AlMN <- mxAlgebra(XMN %*% t(XMN), name="AlMN")
ClMN <- mxAlgebra(YMN %*% t(YMN), name="ClMN")
ElMN <- mxAlgebra(ZMN %*% t(ZMN), name="ElMN")

AlCO <- mxAlgebra(XCO %*% t(XCO), name="AlCO")
ClCO <- mxAlgebra(YCO %*% t(YCO), name="ClCO")
ElCO <- mxAlgebra(ZCO %*% t(ZCO), name="ElCO")

CO_ACons2 <- mxMatrix("Full", 1, 1, free=FALSE, values=0, labels="AlCO[2,2]", name="CO_ACons2")

Example 1 runs but the output of the constrained correlation matrix is no different than the base model (seen in attached output)

In this second example, I want to constrain corLMN[1,2] and corLCO[1,2] to be the same.


VarLMN <- mxAlgebra(expression = AlMN + ClMN + ElMN, name="VarLMN")
VarLCO <- mxAlgebra(expression = AlCO + ClCO + ElCO, name="VarLCO")

corLMN <- mxAlgebra(cov2cor(VarLMN), name="corLMN")
corLCO <- mxAlgebra(cov2cor(VarLCO), name="corLCO")

MN_CorCons12 <- mxMatrix("Full", 1, 1, free=TRUE, labels="corLMN[1,2]", name="MN_CorCons12")
CO_CorCons12 <- mxMatrix("Full", 1, 1, free=TRUE, labels="corLCO[1,2]", name="CO_CorCons12")
CorCons12 <- mxConstraint(MN_CorCons12 == CO_CorCons12, name="CorCons12")

The model does not run in this example, I get an error "entity unknown"

Replied on Mon, 08/20/2018 - 10:50
Picture of user. AdminRobK Joined: 01/24/2014

I am trying to constrain the results of an algebra, either to a fixed value or constraining the results of two algebras to be equivalent. I am using https://openmx.ssri.psu.edu//wiki/mxConstraint-help as a starting point.

Unfortunately, the wiki is extremely out-of-date. What it says may not be accurate for OpenMx version 2.x.

Try replacing this,

AlCO <- mxAlgebra(XCO %*% t(XCO), name="AlCO")
CO_ACons2 <- mxMatrix("Full", 1, 1, free=FALSE, values=0, labels="AlCO[2,2]", name="CO_ACons2")

, with this,

CO_ACons2 <- mxConstraint(AlCO[2,2] == 0, name="CO_ACons2")

. Try replacing this,

MN_CorCons12 <- mxMatrix("Full", 1, 1, free=TRUE, labels="corLMN[1,2]", name="MN_CorCons12")
CO_CorCons12 <- mxMatrix("Full", 1, 1, free=TRUE, labels="corLCO[1,2]", name="CO_CorCons12")
CorCons12 <- mxConstraint(MN_CorCons12 == CO_CorCons12, name="CorCons12")

, with this,

CorCons12 <- mxConstraint(corLMN[1,2] - corLCO[1,2] == 0, name="CorCons12")

I think the syntax in your second example ought to work, so you may have discovered a bug. I suspect the syntax in your first example hasn't worked since before version 1.3, if it ever actually did.

Replied on Mon, 08/20/2018 - 11:32
Picture of user. AdminRobK Joined: 01/24/2014

This should also work:

MN_CorCons12 <- mxMatrix("Full", 1, 1, free=F, labels="corLMN[1,2]", name="MN_CorCons12")
CO_CorCons12 <- mxMatrix("Full", 1, 1, free=F, labels="corLCO[1,2]", name="CO_CorCons12")
CorCons12 <- mxConstraint(MN_CorCons12 == CO_CorCons12, name="CorCons12")

It's sort of a like a matrix element containing a definition variable: the element doesn't have a free value of its own, but rather, its value is "fixed" to the value of whatever its label references (in this case, an algebra element).
Replied on Mon, 08/20/2018 - 11:38
Picture of user. AdminNeale Joined: 03/01/2013

Seems to me that we should warn users when using labels to constrain elements that have been declared as fixed (say because they are the results of an algebra - it's a reasonable state to guess) that it's not going to work. Or we should make it work either way. Lacking repair, we should issue either a warning or error, methinks.
Replied on Mon, 08/20/2018 - 11:50
Picture of user. AdminRobK Joined: 01/24/2014

OpenMx's behavior in the first example seems reasonable to me. Consider this short script:

require(OpenMx)
data(demoOneFactor)
factorModel <- mxModel(
"One Factor",
mxMatrix("Full", 5, 1, values=0.8,
free=TRUE, name="A"),
mxMatrix("Symm", 1, 1, values=1,
free=FALSE, name="L"),
mxMatrix("Diag", 5, 5, values=1,
free=TRUE, name="U"),
mxAlgebra(A %*% L %*% t(A) + U, name="R"),
mxExpectationNormal(covariance = "R",
dimnames = names(demoOneFactor)),
mxFitFunctionML(),
mxMatrix("Full", 1, 1, free=F, values=1, labels="R[5,5]", name="foo"),
mxData(cov(demoOneFactor), type="cov", numObs=500))
summary(factorModelFit <- mxRun(factorModel))
mxEval(R,factorModelFit,T) #<--Constraint not in effect
mxEval(R,factorModel,T) #<--R at start values
mxEval(foo,factorModel,T) #<--R[5,5] at start values
mxEval(foo,factorModelFit) #<--Also R[5,5] at start values
mxEval(foo,factorModelFit,T) #<--R[5,5] at MLE

The sole element of 'foo' is initialized at 1, per argument to mxMatrix(). If computed before `mxRun()`, 'foo' is the value of what it references, at the start values. After `mxRun()` It nominally retains that value, but if computed, it returns the value of what it references, at the solution.
Replied on Tue, 08/21/2018 - 17:50
No user picture. szellers Joined: 04/04/2018

Thanks for the help!


CO_ACons2 <- mxConstraint(AlCO[2,2] == 0, name="CO_ACons2")

The above does work!

I'm still trying to find a solution to constrain the solutions of two algebras to be equivalent. I have tried three things suggested here.

For this code, the model runs but there is no difference in output.

MN_CorCons1 <- mxMatrix("Full", 1, 1, free=FALSE, labels="corLMN[1,2]", name="MN_CorCons1")
CO_CorCons1 <- mxMatrix("Full", 1, 1, free=FALSE, labels="corLCO[1,2]", name="CO_CorCons1")
CorCons1 <- mxConstraint(MN_CorCons1 == CO_CorCons1, name="CorCons1")

LGFit$output$algebras$MZCO.corLCO
[,1] [,2] [,3]
[1,] 1.0000000 0.7882587 0.3905030
[2,] 0.7882587 1.0000000 0.8625979
[3,] 0.3905030 0.8625979 1.0000000

LGFit_Con$output$algebras$MZCO.corLCO
[,1] [,2] [,3]
[1,] 1.0000000 0.7882599 0.3905036
[2,] 0.7882599 1.0000000 0.8625976
[3,] 0.3905036 0.8625976 1.0000000

LGFit$output$algebras$MZMN.corLMN
[,1] [,2] [,3]
[1,] 1.0000000 0.8372529 0.3190484
[2,] 0.8372529 1.0000000 0.6936678
[3,] 0.3190484 0.6936678 1.0000000

LGFit_Con$output$algebras$MZMN.corLMN
[,1] [,2] [,3]
[1,] 1.0000000 0.8372541 0.3190496
[2,] 0.8372541 1.0000000 0.6936728
[3,] 0.3190496 0.6936728 1.0000000

When I run the code below this, the model does not run and results in “Error: The label with square brackets has been assigned to a free parameter in matrix 'MZMN.MN_CorCons1' at row 1 and column 1”

MN_CorCons1 <- mxMatrix("Full", 1, 1, free=TRUE, labels="corLMN[1,2]", name="MN_CorCons1")
CO_CorCons1 <- mxMatrix("Full", 1, 1, free=TRUE, labels="corLCO[1,2]", name="CO_CorCons1")
CorCons1 <- mxConstraint(MN_CorCons1 == CO_CorCons1, name="CorCons1")

When I run the code below this, the model does not run and results in “Error: Unknown reference 'corLMN' detected in the entity 'CorCons12' in model 'LinearGrowthACE'”

CorCons12 <- mxConstraint(corLMN[1,2] - corLCO[1,2] == 0, name="CorCons12")

Replied on Tue, 09/04/2018 - 17:16
Picture of user. AdminRobK Joined: 01/24/2014

In reply to by szellers

When I run the code below this, the model does not run and results in “Error: The label with square brackets has been assigned to a free parameter in matrix 'MZMN.MN_CorCons1' at row 1 and column 1”

MN_CorCons1 <- mxMatrix("Full", 1, 1, free=TRUE, labels="corLMN[1,2]", name="MN_CorCons1")
CO_CorCons1 <- mxMatrix("Full", 1, 1, free=TRUE, labels="corLCO[1,2]", name="CO_CorCons1")
CorCons1 <- mxConstraint(MN_CorCons1 == CO_CorCons1, name="CorCons1")

As discussed upthread, that syntax is only supposed to work with `free=F`. As for the other two blocks of code, if you're putting the new MxMatrices and MxConstraints directly into the container model, you may need to prefix the names of algebras that are in submodels appropriately, e.g. "MZMN.corLMN[1,2]" and "MZCO.corLCO[1,2]".