You are here

Constraining results of an algebra

7 posts / 0 new
Last post
szellers's picture
Offline
Joined: 04/04/2018 - 14:52
Constraining results of an algebra
AttachmentSize
Plain text icon CO_A2_Output.txt53.87 KB

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"

AdminRobK's picture
Offline
Joined: 01/24/2014 - 12:15
wiki is out-of-date
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.

AdminRobK's picture
Offline
Joined: 01/24/2014 - 12:15
use free=FALSE in 2nd example

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).

AdminNeale's picture
Offline
Joined: 03/01/2013 - 14:09
Warn at least.

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.

AdminRobK's picture
Offline
Joined: 01/24/2014 - 12:15
first example

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.

szellers's picture
Offline
Joined: 04/04/2018 - 14:52
Tried a few things

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")
AdminRobK's picture
Offline
Joined: 01/24/2014 - 12:15
namespace
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]".