Reference: Q0037
Article Last Modified on 30-Sep-2006
My add-in function expects a matrix input to have same number of rows as it has columns. Can I use the Function Wizard to specify this constraint?
You can modify your arguments to be bounded input arrays. The XLL+ Function Wizard has a tab which lets you set the bounds of an array, so that they are tied to a named variable (or to a constant). The code which is generated will automatically check that all matrix and vector inputs satisfy the constraints you apply.
By using the same named variable for the height of the input and also for its width, you can ensure that height of the input is equal to its width.
If the input is not square, then an error value is returned, e.g. if x
has 3 rows and 4 columns:
#Error: expected 3 columns in x
Problem: constrain the height of a matrix to equal its width.
Create a new function, SquareMatrix(), using the XLL+ Function
Wizard. It takes one argument x, which is defined as a matrix of
doubles.
Select the Dimensions column of the row containing the definition of x,
and click on the ... button. (Or use the short-cut Ctrl+E.)
This will display the Edit Argument dialog.
Select the Array tab.
In the Rows box, check the Bounded check-box and set the upper bound (UBound) to be cx, as shown below.
In the Columns box, check the Bounded check-box and set the upper bound (UBound) also to be cx, as shown below.
Inspect the changes to the Function Wizard. The Dimensions column now contains
the new definition of x: Matrix (0 to cx)(0 to cx).
The code generated is shown below:
// Function: SquareMatrix
// Purpose: Requires an input matrix to be square
//{{XLP_SRC(SquareMatrix)
// NOTE - the FunctionWizard will add and remove mapping code here.
// DO NOT EDIT what you see in these blocks of generated code!
IMPLEMENT_XLLFN2(SquareMatrix, "RP", "SquareMatrix", "x",
"User Defined", "Requires an input matrix to be square",
"No description provided\000", "B0(0,cx)0(0,cx)x No descripti"
"on provided\0appscope=1\0", 1)
extern "C" __declspec( dllexport )
LPXLOPER SquareMatrix(const COper* x)
{
XLL_FIX_STATE;
CXlOper xloResult;
BOOL bOk = TRUE;
long cx = -1;
MTX_PTRS<double> matx;
bOk = bOk && x->ReadMatrix(matx, "x", xloResult, &cx, &cx, XLA_ARRAY_FLAGS_NUMERIC_STD, 0, 0);
if (!bOk)
return xloResult.Ret();
//}}XLP_SRC
// TODO - Set the value of xloResult
return xloResult.Ret();
}
The interesting code is shown in bold above.
cx, which we entered (twice) as UBound in the
Edit Argument dialog, is declared, and is initialized to -1. This
value represents "not yet known".cx is passed to COper::ReadMatrix as the value for
plUBound1 and also for plUBound2.x, the bound value
cx contains -1 (meaning "not yet known"), and ReadMatrix simply sets
its value to the height of x.x and compares
it to cx (which now contains the number of rows in x).
Since cx contains a non-negative integer, it is treated as a fixed
size constraint. If x does not contain cx columns
then an error is returned.If, for example, x contains 3 rows and 4 columns, then the
following error value is returned
#Error: expected 3 columns in x
and the function does not continue.
FAQ #0034 discusses various ways to use bounded input
arrays to constrain the bounds of an input.
Bounded input arrays - technical note in the online documentation.
Argument Dialog - Array Tab - tools help in the online documentation.