構造体の中身を一行のテキストに保存するに至った経緯
- シュミレーション条件を決める変数を1つの構造体に入れると管理しやすい
- 条件と結果を関連付けして保存したい
- とはいえ毎回fprintf("p1: %d, p2: %d", parameter1, parameter2);と書くのが手間
MATLABの構造体の中身すべてを文字列で取得するには
取得した文字列をMATLABコマンドとして処理するeval関数を使用し取得していきます。
※evalに関する解説は記事の後半をお読みください。
MATLABの構造体情報(変数名と値)をまとめて取得するコード例
例えば次の様にすれば、構造体内部の変数名前と値を取得できます。
注)1 階層分しか要素を持たない単純な構造の構造体を想定しています。
getStructInfo.m (要素がすべてスカラーの場合)
function nv_list_str = getStructInfo(st)
ele_name = fieldnames(st);
nv_list = [];
dot = ",";
for idx = 1:length(ele_name)
%見た目を整える
if idx==length(ele_name)
dot = "";
end
%idx番目の要素の値
ele_value = eval("st." + ele_name(idx));
%要素の名前と値をテキストで結合
new_name = ele_name(idx) + ": " + ele_value + dot;
%配列に追加
nv_list = [nv_list new_name];
end
nv_list_str = join(nv_list);
end
getStructInfo_vec.m (要素の一部にベクトルも含む場合)
function nv_list_str = getStructInfo_vec(st)
ele_name = fieldnames(st);
nv_list = [];
dot = ",";
for idx = 1:length(ele_name)
%見た目を整える
if idx==length(ele_name)
dot = "";
end
%idx番目の要素の値
ele_value = eval("st." + ele_name(idx));
%要素の名前と値をテキストで結合
new_name = ele_name(idx) + ": " + "[" + num2str(ele_value) + "]" + dot;
%配列に追加
nv_list = [nv_list new_name];
end
nv_list_str = join(nv_list);
end
getStructInfoの使用例
次のように使用します。
st.a = 1;
st.b = 20;
st.c = 30;
st.d = 3.14;
getStructInfo(st)
>> ans = a: 1, b: 20, c: 30, d: 3.14
st.a = 123;
st.b = (1:4);
st.c = (30:2:34);
st.d = 50;
getStructInfo_vec(st)
>> ans = a: [123], b: [1 2 3 4], c: [30 32 34], d: [50]
一行のテキストとして表示することで、構造体の中身が一目瞭然になりました。
パラメータ数や、パラメータ内の要素数が増えると逆に見にくくなってしまう可能性もありそうですが、10個程度のパラメータ状況を、ファイル名に使いたい場合には、十分効果を発揮してくれそうです。
補足: eval関数の扱い
eval関数は、テキストをMATLABのコードとして読み取り、処理してくれる非常に便利な関数です。
しかしながら、逆に何でも操作ができてしまうことに加え、多用することで可読性が著しく低下するため、MATLABでは非推奨関数とされています。
使用される際は、デバッグ時にこちらでもエラーが起こる可能性を念頭に置きながら使用しましょう。
私も、eval関数を多用したコードは非常に読みづらいため、極力使用は避けるようにしています。
とはいえ、手元の作業を自動化する際には、便利な関数なため、必要箇所でピンポイントで使用していくことはありなのかなと考えています。