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

1 回表示 (過去 30 日間)
FM
FM 2021 年 4 月 22 日
編集済み: FM 2021 年 5 月 28 日
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.

採用された回答

Walter Roberson
Walter Roberson 2021 年 4 月 22 日
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 件のコメント
Walter Roberson
Walter Roberson 2021 年 4 月 23 日
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 2021 年 4 月 23 日
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!

サインインしてコメントする。

その他の回答 (1 件)

FM
FM 2021 年 5 月 28 日
編集済み: FM 2021 年 5 月 28 日
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)"

カテゴリ

Help Center および File ExchangeCell Arrays についてさらに検索

製品


リリース

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by