using mxMatrix

Posted on
Picture of user. tbates Joined: 07/31/2009

Shouldn't matrices of type "Symm" only take one triangle of data? Otherwise you can do this: run runs fine, but sees asymmetrical values in the matrix

s <- mxMatrix(type="Symm", 3, 3,
c(FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE),
c(1, .9, .8, .8, 1, .8, .8, .8, 1),
c(NA, "free1", "free2", "free1", NA, "free3", "free2", "free3", NA))
s

Replied on Thu, 08/06/2009 - 18:25
Picture of user. mspiegel Joined: 07/31/2009

At the moment, error checking happens when you run the model. So in your example above, mxRun(mxModel(s)) will throw an error. If the user inputs only one triangle of data, then the lower triangle and upper triangle are populated with those values.

Replied on Thu, 08/06/2009 - 20:37
Picture of user. Steve Joined: 07/30/2009

In reply to by mspiegel

This example points out that there are two classes of errors.

A. Some errors result in problems that are encapsulated within a single mxFoo function call.

B. Other errors are only evident when the entire model is evaluated together.

Tim Bates example is a Class A error. Catching Class A errors at their source is a service to the user since it localizes (both in space and time) their debugging.

Replied on Fri, 08/07/2009 - 07:06
Picture of user. tbates Joined: 07/31/2009

In reply to by Steve

Indeed: Much nicer to catch things when they occur - and much easier to give meaningful feedback
"You provided asymmetrical input to symmetrical matrix 'A' "

rather than
"Model parser got unexpected value, expected matrix" or similar.

Would it be desirable to throw an error on getting value array of length other than sigma(n) where n=1 to nrow?

Or is that just making life unnecessarily hard? It would make it impossible to commit the asymmetrical symm-matrix error.

Replied on Fri, 08/07/2009 - 07:24
Picture of user. mspiegel Joined: 07/31/2009

In reply to by Steve

I've added error checking to the mxMatrix() function. I can see the possibility of the user wanting to create an incomplete and invalid matrix to use as a template. But the verification call is exactly one line, so its easy to reverse this decision.

Replied on Fri, 08/07/2009 - 08:11
Picture of user. Steve Joined: 07/30/2009

In reply to by mspiegel

Thanks for the fix. I think it's the right thing to do. In my opinion, the number of people helped by proximal error checking in this case will exceed the number of people frustrated. And the person who is frustrated will just say, "oh, I guess I couldn't fool the program that way." and maybe figure out that procedural model definition will help him/her get the same job done faster/easier anyway.

Replied on Fri, 08/07/2009 - 08:47
Picture of user. tbates Joined: 07/31/2009

In reply to by mspiegel

Thanks mike!

In the same vein:

'Diag'
error if nrow != ncol. : "Symmetrical matrices must be square: You provided %i rows and %i columns!"
error if any values off the diagonal are free : "Error in matrix %name: No off-diagonal cells in an Diagonal matrix can be free"
error if any values off the diagonal are != 0 : "Error in matrix %name: All values off the diagonal of an Diagonal matrix must be 0"

'Iden'
error if nrow != ncol. : "Symmetrical matrices must be square: you provided %i rows and %i columns!"
error if any values are free : "Error in matrix %name: No cells in an Identity matrix can be free"
error if any values on the diagonal are != 1 : "Error in matrix %name: All values on the diagonal of an Identity matrix must be 1"
error if any values off the diagonal are != 0 : "Error in matrix %name: All values off the diagonal of an Identity matrix must be 0"

'Symm'
error if (nrow != ncol) : "Symmetrical matrices must be square: you provided %i rows and %i columns!"
done
error if any values are not mirrored in the upper and lower triangles
'Unit'
error if any values are free : "Error in matrix %name: No cells in a Unit matrix can be free"
error if any value != 1 : "Error in matrix %name: All values in a Unit matrix must be 1"
'Zero'
error if any values are free : "Error in matrix %name: No cells in a Zero matrix can be free"
error if any values != 0 : "Error in matrix %name: All values in a Zero matrix must be 0"

Replied on Tue, 08/25/2009 - 07:35
Picture of user. tbates Joined: 07/31/2009

Q: Convert "Full" to "Lower"?

Is there a way in OpenMx to convert a matrix from Full to Lower?

I would like to be able to say mxMatrix(, "Lower", fullMatrixIPreparedEarlier)

But of course if you input the values matrix of a Full, it barfs on the non NA values in the upper triangle...

Replied on Thu, 08/27/2009 - 20:15
Picture of user. tbates Joined: 07/31/2009

cLabels = c(
+ "v1c1", NA, NA,
+ "v2c1", "v2c2", NA,
+ "v3c1", "v3c2", "v3c3"
+ )
>
> cMatrix = mxMatrix("Lower", nrow=3, ncol=3, free=TRUE, values=.5, labels=cLabels, name="c") #
Error: Upper triangle of labels matrix in lower matrix 'c' is not all NAs!

The error message seems wrong or misleading. the upper triangle was all NAs.

Replied on Thu, 08/27/2009 - 20:35
Picture of user. tbates Joined: 07/31/2009

In reply to by Steve

hmm.. yes setting byrow=TRUE fixes that error... but sending just the lower triangle in row order works without altering byrow:

cLabels = c(
"v1c1",
"v2c1", "v2c2",
"v3c1", "v3c2", "v3c3"
)

cMatrix = mxMatrix("Lower", nrow=nVar, ncol=nVar, free=TRUE, values=.5, labels=cLabels, name="c")

So the default direction changes depending on whether you give a lower or a full set of values: if full, byrow=FALSE is the default, but if only a lower is given, then that fills as if byrow=TRUE?

Replied on Thu, 08/27/2009 - 21:22
Picture of user. Steve Joined: 07/30/2009

In reply to by mspiegel

Yep, byrow=TRUE produces the correct result in either the NAs case or the lower triangular input case. No switching involved. If you want to input a vector into your matrices in this form:

> cLabels = c(
+ "v1c1",
+ "v2c1", "v2c2",
+ "v3c1", "v3c2", "v3c3"
+ )

always use byrow=TRUE.

Replied on Fri, 08/28/2009 - 09:58
Picture of user. Steve Joined: 07/30/2009

In reply to by tbates

I've thought some about that. And it is tempting. But nothing else in R has byrow=TRUE as a default. This is likely due to the dependence on CBLAS. But for whatever reason, R has byrow=FALSE defaults even when they don't make sense. (try using the defaults on write() on a data file and the read it back in with read.table() if you want some confusion)

Anyway, if people want to override defaults in R, they can do so. They can use the same methods to do so for OpenMx. But I think it would cause more confusion rather than less if we do things opposite of R's defaults.

Replied on Fri, 08/28/2009 - 11:48
Picture of user. tbates Joined: 07/31/2009

In reply to by Steve

I think in R you can find a counter-example for any consistency :-)

In general, my argument (and yours too I think from what you say?) would be that our defaults should reflect the common settings that users want, not the common setting programmers chose.

Anyhow: I'll leave it to the hive mind, having made my buzz :-)

Off too add byrow=TRUE to everything...

Replied on Fri, 08/28/2009 - 15:00
Picture of user. mspiegel Joined: 07/31/2009

In reply to by Steve

Based on the discussion of today's developer meeting, a global option in R will be added to select the default behavior of the byrow argument. The standard value for this option will be FALSE. Any documentation on the website should assume the standard value of FALSE.

Replied on Sat, 09/12/2009 - 09:59
Picture of user. tbates Joined: 07/31/2009

an MxMatrix doesn't have a slot for its row or column count.

If we want to get the size of an mxMatrix, we should get the size of its values then get the dim of that?

dim(matrix@values)
--> [3,3]

Replied on Sun, 10/11/2009 - 16:29
Picture of user. jssteele Joined: 10/11/2009

Greetings all,
I am not sure this is the best place to post this but I have encountered a rather odd quirk with the mxMatrix command.
There is a shortcut in Chapter 3 of the documentation that uses 'T' & 'F' instead of the full 'TRUE' and 'FALSE' for the specification of the free parameters in the matrix. However this shortcut only works if the matrix is not of type 'Symm'. Otherwise it throws and error:

Error: Illegal number of elements (###) for free matrix in SymmMatrix constructor.

Changing the free parameter values to 'TRUE' & 'FALSE' fixes it, but this is allowed for matrices of type 'Full'.

==== Begin Example ====
# matrix specification error from documented shortcut in free matrix from Chapter 3.
# the first one works notice "TRUE" and "FALSE" are spelled out
s1 <- mxMatrix(type="Symm", nrow=3, ncol=3,
	free=c(
		FALSE, TRUE, TRUE, 
		TRUE, FALSE, TRUE, 
		TRUE, TRUE, FALSE),
	values=c(
		1, .8, .8, 
		.8, 1, .8, 
		.8, .8, 1),
	labels=c(
		NA, "free1", "free2", 
		"free1", NA, "free3", 
		"free2", "free3", NA),
	name="S1");

# the second one does not, notice the use of "T" and "F" instead.
s2 <- mxMatrix(type="Symm", nrow=3, ncol=3,
	free=c(
		F, T, T, 
		T, F, T, 
		T, T, F),
	values=c(
		1, .8, .8, 
		.8, 1, .8, 
		.8, .8, 1),
	labels=c(
		NA, "free1", "free2", 
		"free1", NA, "free3", 
		"free2", "free3", NA),
	name="S2");

# The error
Error: Illegal number of elements (###) for free matrix in SymmMatrix constructor.

# however the shortcut works for "Full" matrices
s3 <- mxMatrix(type="Full", nrow=3, ncol=3,
	free=c(
		F, T, T, 
		T, F, T, 
		T, T, F),
	values=c(
		1, .8, .8, 
		.8, 1, .8, 
		.8, .8, 1),
	labels=c(
		NA, "free1", "free2", 
		"free1", NA, "free3", 
		"free2", "free3", NA),
	name="S3");

==== End Example ====
Oh and just an aside, I haven't been able to get the formatting the way I want it above, I tried <code> tags but it didn't preserve the whitespace, so I switched to <pre> tags... Minor nit I know.
Thats all for now.
-Joel

Replied on Sun, 10/11/2009 - 16:54
Picture of user. tbates Joined: 07/31/2009

In reply to by jssteele

Both ways work the same.

Type "T" and "F" into R to see what they are set too... I'm guessing not to TRUE and FALSE

The 1-char codes are a very handy short-cut, but rely on the user not changing them to other values.

Caught me once (there's a post here to prove it). good practice from time to time to say:

if(T==TRUE & F==FALSE){

 

"OK"

} else {

"oops"

}