Render 1D column of Optimizati​onVariable​/Optimizat​ionExpress​ion objects to string?

1 view (last 30 days)
In Matlab 2019a, I have a table wherein a column `IFpvfd` is an `OptimizationVariable` array:
myTable = table( [1:3]' , ...
optimvar( 'IFpvfd' , 3 , 1 , 'Type','integer' , ...
'LowerBound',0 , 'UpperBound',1 ) , ...
'VariableNames' , {'RowNbr' 'IFpvfd'} )
myTable = 3×2 table
RowNbr IFpvfd
______ ___________________________________________
1 [1x1 optim.problemdef.OptimizationVariable]
2 [1x1 optim.problemdef.OptimizationVariable]
3 [1x1 optim.problemdef.OptimizationVariable]
showvar( myTable.IFpvfd )
[ IFpvfd(1) ]
[ IFpvfd(2) ]
[ IFpvfd(3) ]
I want to add a column `IFpvfd2` that shows the `OptimizationVariable` more readably, either as a string array or cell array of character arrays:
RowNbr IFpvfd IFpvfd2
______ ___________________________________________ _________
1 [1x1 optim.problemdef.OptimizationVariable] IFpvfd(1)
2 [1x1 optim.problemdef.OptimizationVariable] IFpvfd(2)
3 [1x1 optim.problemdef.OptimizationVariable] IFpvfd(3)
I was hoping that there was a function to do this using arrayfun:
myTable.IFpvfd2 = arrayfun( @SomeFunc , myTable.IFpvfd )
For `SomeFunc`, I don't think I can use an anonymous function based on `sprintf` because the formatting string only accepts primitive data:
@(x) sprintf( 'Some Formatting String' , x )
I can't use `showvar` or `writevar`, as they send the output to either console and a text file without providing a return argument.

Accepted Answer

Walter Roberson
Walter Roberson on 22 Apr 2021
myTable = table( [1:3]' , ...
optimvar( 'IFpvfd' , 3 , 1 , 'Type','integer' , ...
'LowerBound',0 , 'UpperBound',1 ) , ...
'VariableNames' , {'RowNbr' 'IFpvfd'} )
myTable = 3×2 table
RowNbr IFpvfd ______ ___________________________________________ 1 [1×1 optim.problemdef.OptimizationVariable] 2 [1×1 optim.problemdef.OptimizationVariable] 3 [1×1 optim.problemdef.OptimizationVariable]
myTable.IFpvfd2 = rowfun( @SomeFunc , myTable, 'InputVariables', 'IFpvfd' )
myTable = 3×3 table
RowNbr IFpvfd IFpvfd2 Var1 ______ ___________________________________________ _________ 1 [1×1 optim.problemdef.OptimizationVariable] IFpvfd(1) 2 [1×1 optim.problemdef.OptimizationVariable] IFpvfd(2) 3 [1×1 optim.problemdef.OptimizationVariable] IFpvfd(3)
function S = SomeFunc(OV)
warnstate = warning('off', 'MATLAB:structOnObject');
OVS = struct(OV);
warning(warnstate);
S = categorical(sprintf("%s(%d)", OVS.Name, OVS.OptimExprImpl.getVarIdx));
end
Note: it did not work to create SomeFunc as an anonymous function: for reasons I do not understand, MATLAB claimed there was no function with that name that was applicable to that datatype.
  5 Comments
Walter Roberson
Walter Roberson on 23 Apr 2021
Ah, I should indeed have coded isfield() not hasfield(), which is something completely different.
The question is...how did you get so much insight into the inner workings of OptimVar?
I used struct2cell() on two different variables, and then I used cellfun(@isequal) between the two . That told me that the only difference between them was in the apparently-empty OptimExprImpl . So I ran methods() on that field and saw getVarIdx which turned out to work.
FM
FM on 23 Apr 2021
That's quite some sleuthing. Some tricks I will have to keep in my back pocket in case I'm against the wall in the future.
Thanks again!

Sign in to comment.

More Answers (1)

FM
FM on 28 May 2021
Edited: FM on 28 May 2021
Here is one solution for a 1D column of OptimizationVariable objects and another solution for a 1D column of OptimizationExpression objects. The latter requires a temporary variable and can't be done in one statement. However, it is able to handle both cases. If I write an source m-file for the conversion function, therefore, I would use the 2nd scheme.
Both schemes assume a 1D column of objects. If the table column consists of a 2D array (which it can!), more sophisticated coding is needed.
% Scheme 1: Test data table with column of OptimizationVariable objects
myTable = table( [1:3]' , ...
optimvar( 'IFpvfd' , 3 , 1 , 'Type','integer' , ...
'LowerBound',0 , 'UpperBound',1 ) , ...
'VariableNames' , {'RowNbr' 'IFpvfd'} );
% Scheme 1: Render OptimizationVariable column into strings
myTable.strIFpvfd = splitlines( string( regexprep( ...
strtrim( evalc( 'showvar( myTable.IFpvfd )' ) ) , ...
'[ \[\]]' , '' ) ) );
myTable = 3×3 table
RowNbr IFpvfd strIFpvfd
______ ___________________________________________ ___________
1 [1x1 optim.problemdef.OptimizationVariable] "IFpvfd(1)"
2 [1x1 optim.problemdef.OptimizationVariable] "IFpvfd(2)"
3 [1x1 optim.problemdef.OptimizationVariable] "IFpvfd(3)"
% Scheme 2: Test data table with column of OptimizationExpression objects
myTable.IFpvfd2 = 0 + myTable.IFpvfd;
% Scheme 2: Render OptimizationExpression column into strings
noisyIFpvfd2 = splitlines( string( regexprep( ...
strtrim( evalc( 'showexpr( myTable.IFpvfd2 )' ) ), ...
'[ \[\]]' , '' ) ) );
myTable.strIFpvfd2 = noisyIFpvfd2(3:4:end)
myTable = 3×5 table
RowNbr IFpvfd strIFpvfd IFpvfd2 strIFpvfd2
______ ___________________________________________ ___________ _____________________________________________ ___________
1 [1x1 optim.problemdef.OptimizationVariable] "IFpvfd(1)" [1x1 optim.problemdef.OptimizationExpression] "IFpvfd(1)"
2 [1x1 optim.problemdef.OptimizationVariable] "IFpvfd(2)" [1x1 optim.problemdef.OptimizationExpression] "IFpvfd(2)"
3 [1x1 optim.problemdef.OptimizationVariable] "IFpvfd(3)" [1x1 optim.problemdef.OptimizationExpression] "IFpvfd(3)"
% Show that Scheme 2 also works with OptimizationVariable
noisyIFpvfd2 = splitlines( string( regexprep( ...
strtrim( evalc( 'showexpr( myTable.IFpvfd )' ) ), ...
'[ \[\]]' , '' ) ) );
noisyIFpvfd2(3:4:end)
ans = 3×1 string array
"IFpvfd(1)"
"IFpvfd(2)"
"IFpvfd(3)"
So the function is:
% strOptVarExpr.m
%----------------
% Convert 1D column of OptimizationVariable or OptimizationExpression
% objects into string representation of the symbolic representation
function strOut = strOptVarExpr( OptVarExpr )
strOut = splitlines( string( regexprep( ...
strtrim( evalc( 'showexpr( OptVarExpr )' ) ), ...
'[ \[\]]' , '' ) ) );
strOut = strOut(3:4:end);
end
The result is:
myTable.strIFpvfd = strOptVarExpr( myTable.IFpvfd );
myTable.strIFpvfd2 = strOptVarExpr( myTable.IFpvfd2 )
myTable = 3×5 table
RowNbr IFpvfd strIFpvfd IFpvfd2 strIFpvfd2
______ ___________________________________________ ___________ _____________________________________________ ___________
1 [1x1 optim.problemdef.OptimizationVariable] "IFpvfd(1)" [1x1 optim.problemdef.OptimizationExpression] "IFpvfd(1)"
2 [1x1 optim.problemdef.OptimizationVariable] "IFpvfd(2)" [1x1 optim.problemdef.OptimizationExpression] "IFpvfd(2)"
3 [1x1 optim.problemdef.OptimizationVariable] "IFpvfd(3)" [1x1 optim.problemdef.OptimizationExpression] "IFpvfd(3)"

Categories

Find more on Cell Arrays in Help Center and File Exchange

Products


Release

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!