2
$\begingroup$

The problem I am having has to do with solving for a matrix of coefficients where I am passing a function that calculates the error between a matrix of observed values and those predicted by some model. The following mathematica code is a very simplified and is just a toy example of what I am trying to do. I have read nearly every post about forcing a function to evaluate only when there are specific values for the coefficients by using ?NumericQ, ?VectorQ and ?MatrixQ although none of the posts indicate how this works and why.(It might be helpful to know why testing if something is numeric, a vector or a matrix will force numerical evaluation.) Here's an example of what I am trying to do:

ClearAll[funct, betas, y, xMat, error];
y = RandomReal[{0, 1}, {10, 3}];
xMat = RandomReal[{0, 1}, {10, 3}];
betas = Table[beta[i, j], {i, 1, 3}, {j, 1, 3}];
funct[betas_?(MatrixQ[#, NumericQ] &), y_, xMat_] := Module[{},

error = Total[Abs[(y - xMat.betas)]^2, 2];
error
]
ans = FindMinimum[funct[betas, y, xMat], betas];

The error message I get is: FindMinimum::srect: Value beta[1.,2.] in search specification {beta[1,1],beta[1,2],beta[1,3]} is not a number or array of numbers.FindMinimum::srect: Value beta[1.,2.] in search specification {beta[1,1],beta[1,2],beta[1,3]} is not a number or array of numbers.

After reading the posts about this, my assumption was that using betas_?(MatrixQ[#, NumericQ] &)

would force evaluation of the function when the variables have specific values. So I'm not sure why this doesn't work. It works in the case where there is only a vector of coefficients, such as:

ClearAll[funct, betas, y, xMat, error];
y = RandomReal[{0, 1}, {10}];
xMat = RandomReal[{0, 1}, {10, 3}];
betas = Table[beta[i], {i, 1, 3}];
funct[betas_?(VectorQ[#, NumericQ] &), y_?(VectorQ[#, NumericQ] &), 
xMat_?(MatrixQ[#, NumericQ] &)] := Module[{},
error = Total[Abs[(y - xMat.betas)]^2, 2];
error
]
ans = FindMinimum[funct[betas, y, xMat], betas];

So, currently I'm at a loss.

$\endgroup$

1 Answer 1

2
$\begingroup$

FindMinimum expects its search variabe to be either a vector or a number -- at least if not explicitly stated otherwise. The syntax with matrix (a list of three vectors) you used is interpreted "find a minimum with repect to beta[1, 1] and expect that is lies in the interval from beta[1, 2] to beta[1, 3]. But that's neither what you mean nor can Mathematica deal with non-numeric intervals, here.

So the following works:

SeedRandom[666];
y = RandomReal[{0, 1}, {10, 3}];
xMat = RandomReal[{0, 1}, {10, 3}];
ans = FindMinimum[funct[betas, y, xMat], Flatten[betas]]

{1.24331, {beta[1, 1] -> -0.357232, beta[1, 2] -> 0.0866559,
beta[1, 3] -> 0.716015, beta[2, 1] -> 0.659248, beta[2, 2] -> 0.664027, beta[2, 3] -> -0.0605147, beta[3, 1] -> 0.530396, beta[3, 2] -> 0.211602, beta[3, 3] -> 0.18978}}

Alternatively, you can aslo give a matrix-valued starting value:

ans = FindMinimum[funct[X, y, xMat], {X, IdentityMatrix[3]}]

{1.24331, {X -> {{-0.357232, 0.0866559, 0.716015}, {0.659248, 0.664027, -0.0605147}, {0.530396, 0.211602, 0.18978}}}}

The latter saves also some boiler plate code...

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.