# umx!

## Constraints

There a many times in modeling that we need to set paths equal to values determined from other aspects of the model. Commonly this can be done using labels - simply giving the same labels to objects we wish to equate. This is computationally efficient. Another way to limit the values a path can take is via upper and lower bounds. There are times, however, when these two methods are insufficient. For instance equating a free path to a fixed path, or, constraining a value using an algebra. That’s when constraints are essential.

Constraints are implemented by providing an algebra to `mxConstraint`. e.g. , like `mxConstraint(A < B[1,1] %*% 2`)

### Constrain K to take a value fixed in another matrix (no real use…)

Here’s an example in which we force the cells of matrix `K` to take the values of a second matrix `limit`. To do this we write an `mxConstraint` with the algebra `K == limit`. The constraint should ensure that K is [1,2; 3,4] - the values of `limit`.

``````m1 <- mxModel("constraint_test",
umxMatrix("limit", type = "Full", nrow = 2, ncol = 2, free = FALSE, values = 1:4),
umxMatrix("K"    , type = "Full", nrow = 2, ncol = 2, free = TRUE),
mxConstraint(K == limit, name = "Klimit_equality"),
mxAlgebra(min(K), name = "minK"),
mxFitFunctionAlgebra("minK")
)
mxEval(K, m1)
``````

You might try and do this using labels: but labels can only equate free parameters, not free and fixed parameters. So…

``````m1 = mxModel(model="con_test",
umxMatrix("limit", nrow = 2, ncol = 2, free = FALSE, labels = paste0("eq", 1:4), values = 1:4),
umxMatrix("K"    , nrow = 2, ncol = 2, free = TRUE, labels = paste0("eq", 1:4)),
mxAlgebra(min(K), name = "minK"),
mxAlgebraObjective("minK")
)
m1 = mxRun(m1)
# Error: In model 'con_test' the name 'eq1' is used as a free parameter in 'con_test.K' and as a fixed parameter in 'con_test.limit'
``````

Here’s another example. In this model, we will maximise the sum `A + B`, with the `mxConstraint` that `A` must exceed `B`, but also remain under the value 10. What do you think the answer will be?

``````m1 = mxModel("max_A_plus_B",
umxMatrix("A", nrow = 1, ncol = 1, free = TRUE),
umxMatrix("B", nrow = 1, ncol = 1, free = TRUE),
mxConstraint(name = 'A_greaterthan_B', A > B),
mxConstraint(name = 'Amax', A < 10),
mxAlgebra(name = "C", A + B),
mxAlgebra(name = "maxC", -C),
mxFitFunctionAlgebra("maxC")
)
m1 = mxRun(m1)

mxEval(c(A=A, B=B, C=C), m1)

#   [,1]
# A   10
# B   10
# C   20

``````

Equate both free parameters of matrix D using labels (both are set to “eq”) but constrain one to take the value log(10)

``````m1 = mxModel("what",
umxMatrix("D", "Full", nrow= 2, ncol= 1, free = TRUE, values = 1, labels = "eq"),
mxConstraint(D[1,1] == log(10) , name = 'fix_cell_D_one'),
mxAlgebra(name = "maxD", -D[2,1]),
mxFitFunctionAlgebra("maxD")
)
m1 = mxRun(m1)
mxEval(D, m1)
#          [,1]
# [1,] 2.302585
# [2,] 2.302585

``````