Loren on the Art of MATLAB

Turn ideas into MATLAB

Class Initialization for Variables

A while ago, I wrote an article sharing some ideas for Programming for Multiple Datatypes. Recently, a colleague asked me a related question for writing some M-code to be used in an embedded MATLAB block in Simulink. He also wanted to be able to generate code from it, using https://www.mathworks.com/products/rtw/ Real-Time Workshop>, and not use it only for simulation. Together, we tried several ideas.

Contents

Conversion to a Known Class

It's typically straight-forward to convert data into a known class. Simply use the name of the class as the conversion method. If that particular conversion is supported, mission accomplished.

md = magic(3);
class(md)
ans =
double

md is a double precision magic square. Now convert md to uint16.

mu16 = uint16(md);
class(mu16)
ans =
uint16

Comparing the arrays, isequal says they are the same since isequal ignores class or type in comparison.

eqvals = isequal(md, mu16)
eqvals =
     1

If you want to check the classes are also the same, you can do something like this.

sameclass = strcmp(class(md),class(mu16))
sameclass =
     0

Conversion to the Class of Another Variable

If you want to write a generic algorithm and you need to be able to handle inputs of a variety of classes, there are some techniques you can use to ensure that the calculations are done in the class you want.

If you want to initialize some variables in your calculation to 0, but in the class of the input, you could use a switch statement and check all of the builtin types. This is tedious, error-prone, and does not scale well.

You could also use the zeros function with the final classname argument. This works for builtin numeric types.

valsaved = zeros(1,1,class(mu16));

Another method that also works for builtin types is using the function cast.

b = cast(0.0,class(mu16));

What do we do if we have an input that behaves like a builtin numeric clas but isn't built in? Some examples might be the sym object in the Symbolic Math Toolbox (assuming the variable contains values that can be converted to numeric ones) or the fi fixed-point object from the Fixed-Point Toolbox.

msym = sym(md);
mfi = fi(md);
whos
  Name           Size            Bytes  Class              Attributes

  ans            1x6                12  char                         
  b              1x1                 2  uint16                       
  eqvals         1x1                 1  logical                      
  fhfi           1x1                16  function_handle              
  fhsym          1x1                16  function_handle              
  md             3x3                72  double                       
  mfi            3x3                    embedded.fi                  
  msym           3x3               622  sym                          
  mu16           3x3                18  uint16                       
  sameclass      1x1                 1  logical                      
  valsaved       1x1                 2  uint16                       
  zfi            1x1                    embedded.fi                  
  zsym           1x1               126  sym                          
  zsym2          1x1               126  sym                          
  zsym3          1x1               126  sym                          

Here's a way to convert to an arbitrary class, using str2func

fhsym = str2func(class(msym));
zsym = fhsym(0.0);
fhfi = str2func(class(mfi));
zfi = fhfi(0.0);
whos
  Name           Size            Bytes  Class              Attributes

  ans            1x6                12  char                         
  b              1x1                 2  uint16                       
  eqvals         1x1                 1  logical                      
  fhfi           1x1                16  function_handle              
  fhsym          1x1                16  function_handle              
  md             3x3                72  double                       
  mfi            3x3                    embedded.fi                  
  msym           3x3               622  sym                          
  mu16           3x3                18  uint16                       
  sameclass      1x1                 1  logical                      
  valsaved       1x1                 2  uint16                       
  zfi            1x1                    embedded.fi                  
  zsym           1x1               126  sym                          
  zsym2          1x1               126  sym                          
  zsym3          1x1               126  sym                          

There is a limitation to this method for Simulink users who want to use embedded MATLAB in the generated code since str2func is not supported for that situation.

Methods that Should (Usually) Work for All Types

So, how to get that initial value to 0 in the right class? Do some arithmetic! Here are two possibilites, illustrated with the sym variable msym.

zsym2 = 0*msym(1);
zsym3 = msym(1)-msym(1);

Why do I say "usually" in the title of this section? The calculations should be supported for classes that behave numerically.

Well, first, it allows me to refer you to a great numerical computing reference.

  • Numerical Methods that [Usually] Work, Forman S. Acton, Harper & Row, Publishers, ISBN 0883854503 (first published in 1970. On my copy the words on the cover are embossed in gold ink, except the word "usually" which is simply impressed.

Second, I have to admit that these methods only work for finite values of the first input. What would you do if you had to guard against non-finite values?

Other Methods or Preferences

Do you have other methods that would work for the conversion to an unknown class? Or preferences on a method to use? If so, please post here.




Published with MATLAB® 7.3

|

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.