MATLAB Mex C API Check if mxarray is base class - matlab

We are using classes in MATLAB which are passed into some C Mex functions. Previously the class objects we have been passing were all the same type, so we have been able to use mxIsClass to verify that the objects are the correct type.
We have however changed the architecture such that the objects are now derived from the original base class to allow customisation. Effectively we have something like:
handle & mixin.Heterogeneous>
BaseClass >
Class1
Class2
Because the base class uses mixin.Heterogeneous, if I pass an array like [Class1_obj Class2_obj], the mex function works as expected - MATLAB treats the array as an array of type BaseClass, and mxIsClass(obj, 'BaseClass') returns true.
The problem arises that when we pass a single object or an array of the same derived class, say [Class1_obj1 Class1_obj2], into the mex function. Because they are the same type, MATLAB treats the array as type Class1, and so mxIsClass(obj, 'BaseClass') returns false because it only considers the class of the object and not the classes it derives from.
I'm trying to figure out if there is a way to get around this problem and make sure that the mxArray* object in the mex function is either a BaseClass directly, or derives from it.
I've considered simply adding checks for every known derived class name, but this seems an ugly way of doing this, not least because if we add more derived classes we need to change the mex function every time.
I suppose I could use the mexCallMATLAB function to call isa in MATLAB which should correctly identify that it is a base class.
I wonder also if there is a way to get MATLAB to pass the object through to the Mex function treating it as a BaseClass object rather than the derived class.
Is there a standard way of acheiving this?

MATLAB's built in isa function can be used to find out if the object or object array is the correct type. The MATLAB function does look at base clases, so doing isa(Class1_obj,'BaseClass') does return true.
I've implemented a function in the mex file that simply calls MATLAB's own isa function to check the type. As a reference for anyone with similar issues, the following is the C function I've written for this task.
//Check the type of class object or object array using MATLAB
static bool isa(mxArray* obj, const char* type) {
//Create LHS/RHS arrays for calling MATLAB
mxArray *lhs[1];
mxArray *rhs[2];
//Return value
bool retVal;
//Populate Inputs to MATLAB isa
rhs[0] = obj;
rhs[1] = mxCreateString(type);
//Call the MATLAB isa function
mexCallMATLAB(1, lhs, 2, rhs, "isa");
//Extract result
retVal = mxIsLogicalScalarTrue(lhs[0]);
//Cleanup
mxDestroyArray(rhs[1]);
mxDestroyArray(lhs[0]);
//Done
return retVal;
}

Related

Validate property to be a sublclass of an abstract class in MATLAB

I'm brand new to OOP in Matlab, and still fairly green when it comes to OOP in general, but what I do know I learnt in C++.
I'm following the Matlab documentation found here Property class and size validation. I want to validate a property so that it must be a specific class and I'm using the example from the link. This is what my class looks like:
classdef simpoint
...
properties
...
outputType dataType
...
end
...
end
In my code dataType is a class I've written. What's more it's abstract.
I'm getting the error
Error defining property 'outputType' of class 'simpoint':
Class dataType is abstract. Specify a default value for property outputType.
The class dataType is abstract to force the user to implement some methods. I'm trying to use property validation to make sure when outputType is set, the class is a subclass of dataType.
I don't really want to set a default value, because forgetting to set outputType should throw an error.
How can I validate outputType to make sure it is a subclass of dataType? Is there a better way to do this in Matlab?
There is a more elegant solution to this problem, which is apparently not well known.
MATLAB has a concept of Heterogeneous Class Hierarchies. This is just fancy way of explicitly declaring the common root class (abstract or not) so that it can be used for property validation. In practice, all you need to do is to make your abstract class inherit from matlab.mixin.Heterogeneous.
Here is a quick example:
classdef (Abstract) AbstractItem < handle & matlab.mixin.Heterogeneous
end
classdef Collection < handle
properties
items AbstractItem
end
end
Then you have no problem:
>> x = Collection
x =
Collection with properties:
items: [0×0 AbstractItem]
Without the matlab.mixin.Heterogeneous inheritance you would get an error like you described:
Error defining property 'items' of class 'Collection'. Class AbstractItem is abstract. Specify a default value for property items.
Your current code uses the following logic:
Create a new simpoint object
Ah this object needs an outputType property
Initialise the outputType property to be an empty dataType object
Uhoh, we can't instantiate an abstract object - error.
Instead, you could also use setters and getters to validate data types. This removes steps 3 and 4 above, since the initial property value will be [].
classdef simpoint < matlab.mixin.SetGet
properties
outputType
end
methods
% ...
end
methods % Setters and getters
function set.outputType( obj, v )
% When the 'obj.outputType = X' is called, this function is
% triggered. We can validate the input first
assert( isa( v, 'dataType' ) );
% If the assertion didn't error, we can set the property
obj.outputType = v;
end
function v = get.outputType( obj )
% Nothing bespoke in the getter (no not strictly needed), just return the value
v = obj.outputType;
end
end
end
For more informative validation, you could use validateattributes instead of assert.
In this case, the default value of outputType will be [] unless you initialise it in the constructor.
Note, by using matlab.mixin.SetGet to enable setters and getters, I've implicitly made your object a handle. In broader OOP terms, the object is now accessed "by reference" rather than "by value". Read more here.
If you don't want a handle then you can remove the < matlab.mixin.SetGet and, by your own comment, define the setter more explicitly
function obj = set.outputType( obj, v )
% Have to return 'obj' if the class isn't a handle.
% ...
end

When does Chapel pass by reference and when by constant?

I am looking for examples of Chapel passing by reference. This example works but it seems like bad form since I am "returning" the input. Does this waste memory? Is there an explicit way to operate on a class?
class PowerPuffGirl {
var secretIngredients: [1..0] string;
}
var bubbles = new PowerPuffGirl();
bubbles.secretIngredients.push_back("sugar");
bubbles.secretIngredients.push_back("spice");
bubbles.secretIngredients.push_back("everything nice");
writeln(bubbles.secretIngredients);
proc kickAss(b: PowerPuffGirl) {
b.secretIngredients.push_back("Chemical X");
return b;
}
bubbles = kickAss(bubbles);
writeln(bubbles.secretIngredients);
And it produces the output
sugar spice everything nice
sugar spice everything nice Chemical X
What is the most efficient way to use a function to modify Bubbles?
Whether Chapel passes an argument by reference or not can be controlled by the argument intent. For example, integers normally pass by value but we can pass one by reference:
proc increment(ref x:int) { // 'ref' here is an argument intent
x += 1;
}
var x:int = 5;
increment(x);
writeln(x); // outputs 6
The way that a type passes when you don't specify an argument is known as the default intent. Chapel passes records, domains, and arrays by reference by default; but of these only arrays are modifiable inside the function. ( Records and domains pass by const ref - meaning they are passed by reference but that the function they are passed to cannot modify them. Arrays pass by ref or const ref depending upon what the function does with them - see array default intent ).
Now, to your question specifically, class instances pass by "value" by default, but Chapel considers the "value" of a class instance to be a pointer. That means that instead of allowing a field (say) to be mutated, passing a class instance by ref just means that it could be replaced with a different class instance. There isn't currently a way to say that a class instance's fields should not be modifiable in the function (other than making them to be explicitly immutable data types).
Given all of that, I don't see any inefficiencies with the code sample you provided in the question. In particular, here:
proc kickAss(b: PowerPuffGirl) {
b.secretIngredients.push_back("Chemical X");
return b;
}
the argument accepting b will receive a copy of the pointer to the instance and the return b will return a copy of that pointer. The contents of the instance (in particular the secretIngredients array) will remain stored where it was and won't be copied in the process.
One more thing:
This example works but it seems like bad form since I am "returning" the input.
As I said, this isn't really a problem for class instances or integers. What about an array?
proc identity(A) {
return A;
}
var A:[1..100] int;
writeln(identity(A));
In this example, the return A in identity() actually does cause a copy of the array to be made. That copy wasn't created when passing the array in to identity(), since the array was passed by with a const ref intent. But, since the function returns something "by value" that was a reference, it's necessary to copy it as part of returning. See also arrays return by value by default in the language evolution document.
In any case, if one wants to return an array by reference, it's possible to do so with the ref or const ref return intent, e.g.:
proc refIdentity(ref arg) ref {
return arg;
}
var B:[1..10] int;
writeln(refIdentity(B));
Now there is no copy of the array and everything is just referring to the same B.
Note though that it's currently possible to write programs that return a reference to a variable that no longer exists. The compiler includes some checking in that area but it's not complete. Hopefully improvements in that area are coming soon.

Force conversion of struct to object in MATLAB loadobj function

I am working with a custom defined class I called "PathObj_Standard". I want to make sure that when I load this class, if the property CalcDate was saved as a cell array it is converted to a standard array. However, I changed the class definition some time ago, so when I use the loadobj function, I am getting a struct instead of an object. The original code I'm using has a lot more properties, so I'd rather not create a new object by assigning property by property from the struct to a new object. Furthermore, I'm also hesitant to change the constructor to accept a struct as an argument.
I tried using the class function inside loadobj, but I am getting a Cannot redefine class 'PathObj_Standard' without a call to 'clear classes' error. Isn't this function supposed to force conversion of a struct to an object? Why doesn't it work within the loadobj function?
classdef PathObj_Standard < handle
properties (SetAccess = protected)
CalcDate;
Name;
end
methods(Static)
function obj=loadobj(s)
if isstruct(s)
obj=class(s,'PathObj_Standard');
else
obj=s;
end
if not(isempty(obj.CalcDate)) && iscell(obj.CalcDate)
obj.CalcDate=cell2mat(obj.CalcDate);
end
end
end
methods
function obj=PathObj_Standard(Name,CalcDate)
obj.Name=Name;
obj.CalcDate=CalcDate;
end
end
The issue is that calling class attempts to create a class which you can't do from within your loadobj. You'll want to call the actual constructor
Also in my experience, the easiest way to construct a class from a struct is to inherit from hgsetget rather than handle as that automatically has the set and get methods of MATLAB's graphics objects and these methods can accept property/values in the form of a struct. In newer versions of MATLAB, you can also use the SetGet mixin
classdef PathObj_Standard < hgsetget
If you do this, you could change your loadobj method to be something like
function obj = loadobj(s)
% Update the input struct as needed
if isfield(s, 'CalcDate') && ~isempty(s.CalcDate) && iscell(s.CalcDate)
s.CalcDate = cell2mat(s.CalcDate);
end
% Call the default constructor
obj = PathObj_Standard();
% Update all properties that were supplied to loadobj
set(obj, s)
end

Can you pass by reference in PeopleCode?

I'm new to PeopleCode and as I'm learning functions, I noticed that in PeopleCode, we'd normally pass value using %PATIENT_ID. A friend told me that you can also pass by reference in PeopleCode but how?
PeopleCode passes by reference for functions.
Function addOne(&num As integer)
&num = &num + 1
End-Function;
Local integer &val = 9;
addOne(&val);
MessageBox(0, "", 0, 0,String(&val));
Results in 10
If you are using App Classes it behaves differently
for methods:
Pass by value for simple types (string, int, number,etc)
Pass by reference for objects (rowsets, records, app classes)
Can pass by reference for simple types using the OUT keyword in the parameter list
method addOne(&num as integer out)
Functions which are defined in the same context as the executing code, e.g. page/component/record/field event PeopleCode, always consider parameters as refernces.
Within Application Classes, parameters of simple types on methods can be defined with the 'out' key word to state that they are a references. Methods also automatically pass parameters as references for complex types. Think: "If there is a lot of data, it is a reference"
This documentation will be very helpful for you.
https://docs.oracle.com/cd/E26239_01/pt851h3/eng/psbooks/tpcr/chapter.htm?File=tpcr/htm/tpcr07.htm
Passing Parameters with Object Data Types
Parameters with object data types are always passed by reference:
/* argument passed by reference */
method storeInfo(&f as File);
If you specify the out modifier for a method parameter with an object
data type, it becomes a reference parameter. This means that the
parameter variable is passed by reference instead of the object that
it is pointing at when passed.
For example, if you pass an object parameter with the out modifier:
method myMethod(&arg as MyObjectClass);
Local MyObjectClass &o1 = create MyObjectClass("A");
Local MyOtherObjectClass &o2 = create MyOtherObjectClass();
&o2.myMethod(&o1);
And inside myMethod this occurs:
Method myMethod
&arg = create MyObjectClass("B");
end-method;
Since the method argument is reassigned within the body of myMethod,
&o1 does not point at the new instance of MyObjectClass (initialized
with "B") after the method call completes. This is because &o1 still
references the original instance of MyObjectClass.
However, if &o1 had been passed with the out modifier, after the
method call completes, &o1 points at whatever the parameter was last
assigned to; in this case, the new instance of MyObjectClass. The
parameter, rather than the object, is passed by reference. Using
the Out Specification for a Parameter
In the following example, a class, AddStuff, has a single public
method, DoAdd. This adds two numbers together, then assigns them as
different numbers. In the signature of the method declaration, the
first parameter is not declared with an out statement, while the
second one is.
class AddStuff
​method DoAdd(&P1 as number, &P2 as number out);
​end-class;
method DoAdd
&X = &P1 + &P2;
&P1 = 1;
&P2 = 2;
end-method;
In the following PeopleCode example, an object named &Aref is
instantiated from the class AddStuff. Two parameters, &I and &J are
also defined.
local AddStuff &Aref = Create AddStuff();
local number &I = 10;
local number &J = 20;
The following code example is correct. &J is changed, because of the
outstatement in the method signature, and because the value is being
passed by reference. The value of &I is not updated.
&Aref.DoAdd(&I, &J); /* changes &J but not &I */
The following code example causes a design time error. The second
parameter must be passed by reference, not by value.
&Aref.DoAdd(10, 20); /* error - second argument not variable */

Timer Thread with passed Function* and Param

I'm working on finishing up my server for my first iPhone application, and I want to implement a simple little feature.
I would like to run a function (perhaps method as well), if another function returns a certain value after a certain waiting period. Fairly simple concept.... right?
Here's my basic foundation.
template <typename T,class TYP>
struct funcpar{
T (*function)(TYP);
TYP parameter;
funcpar(T (*func)(TYP),TYP param);
funcpar& operator=(const funcpar& fp);
};
The goal here is to be able to call funcpar::function(funcpar::parameter) to run the stored function and parameter, and not have to worry about anything else...
When I attempted to use a void* parameter instead of the template, I couldn't copy the memory as an object (because I didn't know what the end object was going to be, or the beginning for that matter) and when I tried multiple timers, every single object's parameter would change to the new parameter passed to the new timer... With the previous struct I have a
question:
Is it possible to make an all-inclusive pointer to this type of object inside a method of a class? Can I templatize a method, and not the whole class? Would it work exactly like a function template?
I have a managing class that holds a vector of these "jobs" and takes care of everything fairly well. I just don't know how to use a templatized function with the struct, or how to utilize templates on a single method in a class..
I'm also utilizing this in my custom simple threadpool, and that's working fairly well, and has the same problems...
I have another question:
Can I possibly store a function with a parameter before it's run? Something like toRun = dontrunmeyet(withThisParameter);? Is my struct even necessary?
Am I going about this whole thing incorrectly?
If this is overly ambiguous, I can set you up with my whole code for context
In order to create a class method that takes a template parameter, yes, it would work almost exactly like a function template. For example:
class A
{
public:
template<typename T>
void my_function(const T& value) { }
};
int main()
{
A test;
test.my_function(5);
return 0;
}
Secondly, for your structure, you can actually turn that into a functor-object that by overloading operator(), lets you call the structure as-if it were a function rather than having to actually call the specific function pointer members inside the structure. For instance, your structure could be re-written to look like this:
#include <iostream>
template <class ReturnType, class ParameterType>
class funcpar
{
private:
ReturnType (*function)(ParameterType);
ParameterType parameter;
public:
funcpar(ReturnType (*func)(ParameterType),ParameterType param):
function(func), parameter(param) {}
funcpar& operator=(const funcpar& fp);
//operator() overloaded to be a function that takes no arguments
//and returns type ReturnType
ReturnType operator() ()
{
return function(parameter);
}
};
int sample_func(int value)
{
return value + 1;
}
int main()
{
funcpar<int, int> test_functor(sample_func, 5);
//you can call any instance of funcpar just like a normal function
std::cout << test_functor() << std::endl;
return 0;
}
BTW, you do need the functor object (or your structure, etc.) in order to bind a dynamic parameter to a function before the function is called in C/C++ ... you can't "store" a parameter with an actual function. Binding a parameter to a function is actually called a closure, and in C/C++, creating a closure requires a structure/class or some type of associated data-structure you can use to bind a function with a specific parameter stored in memory that is used only for a specific instance of that function call.