MATLAB's mxGetFieldByNumber and mxGetFieldNameByNumber return incongruent results - matlab

I have a C mex routine that is iterating over subfields of a structure. Sometimes calling mxGetFieldByNumber() returns NULL when mxGetFieldNameByNumber() returns a string for the same field idx. Here is a toy:
numFields = getNumberOfFields( currentField );
for( fieldIdx = 0; fieldIdx < numFields; fieldIdx ++){
subField = mxGetFieldByNumber( currentField, 0 , fieldIdx );
fieldName = mxGetFieldNameByNumber(currentField, fieldIdx );
}
I have read through the documentation of both functions. A NULL can be returned if (in this example) currentField were not a mxArray which I know is not the case because mxGetFieldNameByNumber() returns something sensible. Insufficient heap space could be the problem but I've checked that and it is on 400kb. NULL can also be returned when no value is assigned to the specified field but I've looked and it appears the value is zero.
Any thoughts?

When a struct is created at the MATLAB level or in a mex routine via mxCreateStruct, not all field elements are necessarily populated. In such case, MATLAB physically stores a NULL pointer (i.e., 0) in those data spots (a struct is essentially an array of mxArray pointers). E.g., take the following code snippet assuming X doesn't exist yet:
X.a = 5;
X(2).b = 7;
The X struct variable actually has four elements, namely X(1).a, X(1).b, X(2).a, and X(2).b. But you only set two of these elements. What does MATLAB do with the other elements? Answer: It simply stores NULL pointers for those spots. If you subsequently access those NULL spots in your MATLAB code, MATLAB will simply create an empty double matrix on the fly.
At the mex level, a similar thing happens. When you first create the struct with mxCreateStruct, MATLAB simply fills all of the element spots with NULL values. Then you can populate them in your code if you want, but note that leaving them as NULL is perfectly acceptable for returning back to MATLAB. The routine mxGetFieldByNumber actually gets the element mxArray pointer, and mxGetFieldNameByNumber gets the name of the field itself ... two very different things. If you get a NULL result from a valid mxGetFieldByNumber call (i.e. your index is not out of range), that simply means this element was never set to anything. You should never get a NULL result from a valid mxGetFieldNameByNumber call, since all field names are required to exist.
If you were to pass in the X created above to a mex routine and then examine prhs[0] you would find the following:
mxGetFieldByNumber(prhs[0],0,0)
returns a pointer to an mxArray that is the scalar double 5
mxGetFieldByNumber(prhs[0],0,1)
returns a NULL pointer
mxGetFieldByNumber(prhs[0],1,0)
returns a NULL pointer
mxGetFieldByNumber(prhs[0],1,1)
returns a pointer to an mxArray that is the scalar double 7
mxGetFieldNameByNumber(prhs[0],0)
returns a pointer to the string "a"
mxGetFieldNameByNumber(prhs[0],1)
returns a pointer to the string "b"

Related

length of a just one array dimension in minizinc

If I define my array like this:
array[_, 1..2] of J: A;
where J is a enum, what function can I use to get the length of the first dimension of A? The length function returns 14 (and states that it doesn't work for multiple dimensions). I had it hard-coded like so in my testing, but it won't always be 13:
constraint forall(row in 1..13)(S[A[row, 2]] >= C[A[row, 1]]);
The length function is really only meant for getting the number of elements. When you want the retrieve indexes of an array, you should instead use the index_set function. This returns the actual index set, which you can iterate over: i in index_set(A)
For multidimensional arrays there are specific functions for each index set of the array. For example, to get the first index set from a two-dimensional array (as in your code fragment) you can use the function index_set_1of2

My mex function ignores my if statement

I have a mex function that takes in a field of a struct in the third input (i.e. prhs[2]), which is a boolean. If true, it will parse information from the fourth input (i.e. prhs[3]). In a nutshell, this is the code excerpt:
mxValue = mxGetField(prhs[3], 0, "change"); mxLogical *change;
change = mxGetLogicals(mxValue);
mexPrintf("true/false: %i \n", *change);
mexEvalString("drawnow;");
if ( change ) {
mexPrintf("...Parsing info... \n");
mexEvalString("drawnow;");
mxValue = mxGetField(prhs[3], 0, "info");
nRows = mxGetM(mxValue); nCols = mxGetN(mxValue);
Eigen::Map<Eigen::VectorXd> info((double *)mxGetPr(mxValue),nRows);
}
As you can see, I do a printout to see whether the input prhs[2] is true or false. Even if the function prints out false, the if statement gets executed regardless, because I can see the printout ...Parsing info....
Why is my MATLAB mex function ignoring my if statement?
C is not MATLAB! C is C!
You are checking if pointer change has a value. It does indeed have a value, a memory direction e.g. #72BA21, to the location where the value of the boolean is stored.
You can either check the contents of whats inside that specific direction if(*change) as #buzjwa suggest, or grab the information on the array, instead of a pointer to it, using mxGetData.
As a side note: learn to debug, or at least, print statements. a simple mexPrintf() call would have shown you what change contains

How to find all values greater than 0 in a cell array in Matlab

I want to find and save all values greater than 0 in an array and save them in a variable called "times". How do I do that? And what is the difference between saving the indices of those cells versus the actual values of the cells?
This is what I have tried, but it must be worng because I get the error:
Undefined operator '>' for input arguments of type
'cell'.
clear all, close all
[num,txt,raw] = xlsread('test.xlsx');
times = find(raw(:,5)>0)
To access the contents of a cell you must use {} instead of ():
idx = find([raw{:, 5}] > 0);
But this gives you the index of the cells of raw containing a positive value. If you want the values instead, you can access them and collect them in a numeric array in this way:
times = [raw{idx, 5}];

Dynamic array or resize extend?

This is a superfluous question. Is there any dynamic array or list in Progress 10.2B?
Example:
I create a base class called "InventoryTransaction". I read a MSSQL table from Progress and I would like to create an instance of InventoryTransaction class for each record found then add it to a "list/array" so I can later process them.
Is there something like MyArray:Add(MyItem) that will increase automatically the array size +1 then will add the instance of MyItem to the array?
I discovered the function EXTENT to set a size dynamically to an array but I do not know the count before reading all the transaction in the MSSQL table. Alternatively, I could execute a "select count(*) from MyTable" before reading all the transaction to retrieve the count and then extent the array.
Thank you!
Happy friday!
Sebastien
You can create "indeterminate" arrays. i.e.
define variable x as decimal extent no-undo.
An indeterminate array variable can be in one of two states: fixed or unfixed, meaning it either has a fixed dimension or it does not. An indeterminate array variable has an unfixed dimension when first defined. You can fix the dimension of an indeterminate array variable by:
Initializing the array values when you define the variable,
Using the INITIAL option
Setting the number of elements in the array variable
Using the EXTENT statement
Assigning a determinate array to the indeterminate array, fixing it to the dimension of the determinate array
Passing array parameters to a procedure, user-defined function, or class-based method, so that the indeterminate array variable is the target for the passing of a determinate array, fixing the indeterminate array to the dimension of the determinate array
Once fixed, ABL treats a fixed indeterminate array as a determinate array.
I just discovered progress.lang.object:
FILE: array.p
/* declaration */
DEFINE TEMP-TABLE arrITem
FIELD Item AS CLASS PROGRESS.lang.OBJECT.
DEFINE VARIABLE oItem AS CLASS Item NO-UNDO.
DEFINE VARIABLE i AS INTEGER NO-UNDO.
/* create 10 products */
DO i = 1 TO 10:
CREATE arrItem.
arrItem.Item = NEW Item("Item_" + STRING(i), "Description_" + STRING(i)).
END.
/* display object information */
FOR EACH arrItem:
ASSIGN oItem = CAST(arrItem.Item,Item).
DISPLAY oItem:ItemNo.
END.
FILE: item.cls
CLASS Item:
DEFINE PUBLIC PROPERTY ItemNo AS CHARACTER
GET.
SET.
DEFINE PUBLIC PROPERTY DESCRIPTION AS CHARACTER
GET.
SET.
/* constructor */
CONSTRUCTOR PUBLIC Item():
END.
CONSTRUCTOR PUBLIC Item(
INPUT strItemNo AS CHARACTER
,INPUT strDescription AS CHARACTER
):
ASSIGN ItemNo = strItemNo.
ASSIGN DESCRIPTION = strDescription.
END.
END CLASS.
Thank you!
Sebastien
The short answer is - no, the 10.2B AVM doesn't allow you to dynamically resize an array.
The long answer is you could (a) add the object to a linked list of objects, or (b) create a temp-table with a Progress.Lang.Object field, create a new TT record for each object instance you want to track, and assign the object's pointer to the TT's PLO field.

objective-c variable length array global scope

is it possible to declare a variable length array with global scope in objective-c?
I'm making a game with a world class, which initializes the world map as a three dimensional integer array. while it's only a two dimensional side scroller, the third dimension of the list states which kinda of block goes at the coordinate given by the first two dimensions
after the initialization function, a method nextFrame: is scheduled (I'm using cocos2d and the CCDirector schedule method). I was wondering how to pass the int[][][] map array from the initialization function to the nextFrame function
I tried using global (static keyword) declaration, but got an error saying that global arrays cannot be variable length
the actual line of code I'm referring to is:
int map[xmax][ymax][3];
where xmax and ymax are the farthest x and y coordinates in the list of coordinates that defines the stage.
I'd like to somehow pass them to nextFrame:, which is scheduled in
[self schedule:#selector(nextFrame:)];
I realize I can use NSMutableArray, but NSMutableArray is kinda a headache for 3-dimensional lists of integers (I have to use wrapper numbers for everything...). is there any way to do this with integer arrays?
You can't have a statically allocated global array of dynamic dimensions in C (of which Objective C is a clean superset). But you can use a global array of any length or size (up to available memory) at runtime by using a global pointer, malloc, and array indexing arithmetic.
static int *map = NULL;
...
map = malloc (dim1 * dim2 * dim3 * sizeof(int)); // in some initialization method
if (map == NULL) { /* handle error */ } // before first array access
...
myElement = map[ index3 + dim2 * ( index2 + dim1 * index1 ) ]; // some macro might be suitable here
Or you could make Objective C getter and setter methods that checks the array and array bounds on every access, since a method can return plain C data types.
Another option, if you know the max dimensions you want to have available and are willing to use (waste) that amount of memory, is to just statically allocate the max array, and throw an exception if the program tries to set up something larger than your allowed max.
I tried using global (static keyword)
declaration, but got an error saying
that global arrays cannot be variable
length
But global array pointers can point to arrays of variable length.