変換した Simulink モデルを小さく読みやすくするリダクションを、それぞれリダクション前とリダクション後のモデルとともに示します。

5 リダクション

Modelifyが初めて実行する変換は非常に冗長な変換です。SimulinkのブロックはC言語のコード内の各演算に対して生成されます。その結果、比較的少量のコードにも関わらず大規模なモデルが生成される可能性があります。この冗長な変換を改善するため、C言語のコードでロジックを表す上で、もしくは、モデルを変更して可読性を向上させる上で必要な数のブロックを減らすリダクションを適用することができます。

リダクションは複数の方法でモデルを簡素化、または、改善します。リダクションは以下の目標の少なくとも1つを達成します:

  • 同じ成果を挙げるよりシンプルなブロック、または、より高いレベルのSimulinkのブロックと置き換えることで、ブロックの数を減らします。
  • 一連のブロックを置き換え、特定のモデルリングガイドラインに準拠させます。
  • シミュレーションの結果に影響を与えないモデルの一部を削除します。オリジナルのC言語のコードにデッドコードが存在するケースが該当します。

個別に各リダクションを有効、または、無効にすることができます。そのため、会社で利用するモデリングガイドラインに一致させる上で必要なリダクションのみ有効にすることが可能です。

「リダクション」ページで、Advanced Arithmetic、Constant Vector、Demux などのリダクションがチェックボックス、カテゴリー、説明とともに並んでいます。

各リダクションの説明を以下に掲載します。各リダクションの説明にはリダクションの前と後のモデルのスクリーンショットが含まれています。画像は横並び、または、上下に表示されます。1点目の画像はリダクション前のモデルを表します。

Absolute Value

このリダクションはロジックが絶対値を示すブロックのセットを絶対値のブロックに置き換えることでモデルを簡素化します。

2点のケースが考えられます。絶対値を返すケース(ケース 1)と負の絶対値を返すケース(ケース 2)です。

ケース 1:
Relational Operator が入力 i を 0 より大きいと判定すると Switch ブロックが i を、そうでなければ i に −1 を掛けた値を渡します。
リダクション前
1 つの Abs ブロックが入力 i を return_value に渡します。
リダクション後
ケース 2:
Relational Operator が i を 0 より大きいと判定すると Switch ブロックが i に −1 を掛けた値を、そうでなければ i を渡します。
リダクション前
Abs ブロックと、それに続く Unary Minus ブロックが入力 i を return_value に渡します。
リダクション後

Advanced Arithmetic

このリダクションは次の方法でモデルの簡素化を行います。

  • Sumブロックから値が0の定数を削除します。
  • Productブロックから値が1の定数を削除します。
  • 同じ入力を算術ブロックに低減します。

Sumブロックから値が0の定数を削除

2つのケースが考えられます: ConstantブロックとSumブロックを単純に削除するケース(ケース1)とUnary Minusブロックを追加する必要があるケース(ケース 2)です。

ケース 1:
Sum ブロックが入力 p に Constant 0 を足し、Product ブロックがその結果に Constant 3 を掛けます。
リダクション前
Product ブロックが p に Constant 3 を直接掛けます。
リダクション後
ケース 2:
Sum ブロックが Constant 0 から入力 p を引き、Product ブロックがその結果に Constant 3 を掛けます。
リダクション前
Unary Minus ブロックが p の符号を反転し、Product ブロックがそれに Constant 3 を掛けます。
リダクション後

Productブロックから値が1の定数を削除

2つのケースが考えられます: ConstantブロックとProductブロックを単純に削除するケース(ケース 1)と逆数のMath Functionブロックを追加する必要があるケース(ケース 2)です。

ケース 1:
Product ブロックが Constant 1 に入力 p を掛け、2 つ目の Product ブロックがその結果に Constant 3 を掛けます。
リダクション前
1 つの Product ブロックが p に Constant 3 を掛けます。
リダクション後
ケース 2:
Product ブロックが Constant 1 を入力 p で割り、2 つ目の Product ブロックがその結果に Constant 3 を掛けます。
リダクション前
Math Function ブロックが p の 1/u を計算し、Product ブロックがそれに Constant 3 を掛けます。
リダクション後

同じ入力を算術ブロックに削除

Productブロックと一致する入力を低減し、Math Functionブロックと置き換えます。

Square (u^2)

Productブロックと一致する入力が2つ存在する場合、2乗のMath Functionブロックに低減されます。

Product ブロックが入力 p を p 自身に掛け、別の Product ブロックが Constant 3 に Constant 3 を掛け、Sum ブロックが 2 つの積を足します。
リダクション前
2 つの Math Function ブロックが p と Constant 3 の u² を計算し、Sum ブロックがそれらを足します。
リダクション後
Power (u^v)

Squareリダクションと同様に、Productブロックに同じ値を持つ入力が2つ以上存在する場合、このリダクションは適用されます。

このリダクションはArithmeticリダクションが有効にされている場合のみ適用され、2つの入力を持つ一連のProductブロックを複数の入力を持つ単一のProductブロックに折り畳みます。

Product ブロックが入力 p を 3 つ掛け合わせます。
リダクション前
Math Function ブロックが p を Constant 3 乗します。
リダクション後
Power of base 10 (10^u)

値10を持つConstantsブロックからProductブロックに2つ以上の入力が存在する場合、Power of base 10 Math Functionブロックに低減されます。

このリダクションはArithmeticリダクションが有効にされている場合のみ適用されます。

Product ブロックが 3 つの Constant 10 を掛け合わせます。
リダクション前
Math Function ブロックが 10 の Constant 3 乗を計算します。
リダクション後
Reciprocal (1/u)

このリダクションは、Productブロックに対する1つめの入力が値1の定数であり、残りの入力はその他のリダクションにより単一のブロックに低減される(例ではSquareリダクション)場合、適用されます。

このリダクションはArithmeticリダクションが有効にされている場合のみ適用されます。

Product ブロックが Constant 1 を入力 p で 2 回割ります。
リダクション前
Math Function ブロックが p を 2 乗し、2 つ目の Math Function ブロックがその逆数を求めます。
リダクション後

Arithmetic

このリダクションは複数のSumブロックを複数の入力を持つ単一のSumブロックに低減します。

Sum ブロックが Constant 3 と入力 p1 を足し、2 つ目の Sum ブロックがその結果から入力 p2 を引きます。
リダクション前
1 つの Sum ブロックが Constant 3 と p1 を足し、p2 を引きます。
リダクション後

同様に複数のProductブロックを複数の入力を持つ単一のProductブロックに低減します。

Product ブロックが Constant 3 に入力 p1 を掛け、2 つ目の Product ブロックがその結果を入力 p2 で割ります。
リダクション前
1 つの Product ブロックが Constant 3 に p1 を掛け、p2 で割ります。
リダクション後

Bus Assignment

同じバスの入力が用いられている複数のBus Assignmentブロックを単一のBus Assignmentブロックに低減します。

2 つの Bus Assignment ブロックが続けて、バス s のフィールド G を Constant 100 に、フィールド B を Constant 255 に設定します。
リダクション前
1 つの Bus Assignment ブロックがバス s の G と B の両方を設定します。
リダクション後

バスの全ての要素が複数のBus Assignmentブロックによって割り当てられている場合、全てBus Creatorブロックに置き換えられます。

3 つの Bus Assignment ブロックが続けて、Constant 0 から作ったバスのフィールド R、G、B を Constant 10、100、255 に設定します。
リダクション前
1 つの Bus Creator ブロックが Constant 10、100、255 を R、G、B としてバスを作ります。
リダクション後

Bus Selector

同じバスの入力が用いられている場合、複数のBus Selectorブロックをまとめます。

2 つの Bus Selector ブロックがバス s からフィールド R と B を取り出し、Sum ブロックがそれらを足します。
リダクション前
1 つの Bus Selector ブロックがバス s から R と B の両方を取り出して Sum ブロックに渡します。
リダクション後

Constant Vector

Constantブロックのグループ、および、単一のベクトル出力を作成するMuxブロックをConstant 1-D ベクトルに置き換えます。

Mux ブロックが Constant 1、3、5 をベクトルにまとめ、Selector ブロックが 1 つの要素を選びます。
リダクション前
1 つの Constant ブロックがベクトル [1; 3; 5] を Selector ブロックに渡します。
リダクション後

同様に、定数のグループ、Muxブロック、および、2次元の配列を作ることが可能なVector Concatenateブロックが存在する場合、行列信号を作る単一のConstantブロックに全て置き換えられます。

3 つの Mux ブロックが Constant 10 から 60 を 2 つずつまとめ、Vector Concatenate ブロックがそれらを 2×3 の行列にまとめます。
リダクション前
1 つの Constant ブロックが 2×3 の行列 [10 30 50; 20 40 60] を持ちます。
リダクション後

Data Type Conversions

変換されたモデルに不要なData Type Conversion ブロックが含まれる場合があります。これは通常オリジナルのC言語のコード内の不要なキャスト演算子によって引き起こされます。

Data Type Conversion ブロックが p を int32 に、d を single に変換してから Product ブロックが割り算をし、3 つ目がその結果を double に変換します。
リダクション前
Product ブロックが Data Type Conversion ブロックなしで p を d で割り、double を出力します。
リダクション後

Dead Paths

これはシミュレーションの出力に影響を与えない図の一部を削除します。デッドコード、または、C言語の関数の利用されていないパラメータが該当します。

入力 p と Constant 2 の Sum の横で、p と Constant 1 の Sum と入力 temp がそれぞれ Terminator で終わっています。
リダクション前
p と Constant 2 の Sum だけが残っています。
リダクション後

Demux

同じベクトル入力が用いられている複数のSelectorブロックを単一のDemuxブロックに低減します。

ベクトルから一部の要素が選択されない場合、Demuxブロックから対応する出力がTerminatorブロックにつなげられます。リダクションは削除予定のSelectorブロックの数が加えられる可能性のあるTerminatorブロックの数よりも多い場合のみ適用されます。

5 つの Selector ブロックが入力 array の要素を 1 つずつ選び、Sum ブロック、Relational Operator、Switch に渡します。
リダクション前
1 つの Demux ブロックが入力 array を 3 つの要素に分け、Sum ブロック、Relational Operator、Switch に渡します。
リダクション後

From and Goto

2つ、または、2つ以上のつながりを持つInportブロックがFromブロックとGotoブロックを使って簡素化されます。大きな図においては、線の分岐が多いと大量の線の交差および混乱を引き起こしかねません。このようなケースでは、GotoブロックとFromブロックの使用により、可読性が改善される可能性があります。

1 本の線が入力 p を Relational Operator に、さらにモデルを横切って Switch に運びます。
リダクション前
Goto ブロックが p に [p] のタグを付け、From ブロックがそれを Relational Operator と Switch に渡します。
リダクション後

Gain

図で定数により積を表すブロックを検索し、Gainブロックと置き換えます。このリダクションはGainブロックに対して単式内の定数を検知し、分類します。

Product ブロックが入力 p に Constant K5 を掛け、また p に Constant 2 と Constant 5 を順に掛け、Sum ブロックが結果を足します。
リダクション前
K5 の Gain ブロックと 2 * 5 の Gain ブロックが p に掛け、Sum ブロックがそれらを足します。
リダクション後

Group Action Transitions

複数の一連のアクションを単一の遷移に移します。

Stateflow のフローチャートが p、i、d、calculated を 1 つずつ 4 つの遷移で計算してから、calculated を MAX と比べます。
リダクション前
同じフローチャートが p、i、d、calculated を、4 つのアクションをまとめた 1 つの遷移で計算します。
リダクション後

Increment

1の加算または減算を表すブロックをそれぞれIncrement Stored Integerブロック、Decrement Stored Integerブロックと置き換えます。

Sum ブロックが入力 p1 に Constant 1 を足し、別の Sum ブロックが入力 p2 から Constant 1 を引き、Product ブロックがその結果を掛けます。
リダクション前
Increment Stored Integer ブロックが p1 に 1 を足し、Decrement Stored Integer ブロックが p2 から 1 を引き、Product ブロックがそれらを掛けます。
リダクション後

Logical Blocks

同じ演算子を持つ複数のLogical Operatorブロックを単一のブロックに低減します。 また、TRUE/FALSE Constants リダクションが有効にされている場合、最適化も実行します。演算子がANDであり、値の一つがfalseの場合、結果は常にfalseになります。このようなケースでは、Logical Operatorブロックを削除し、状況に応じて信号を別ルートに変更します。また、演算子がORで値の一つがtrueの場合も同様の最適化を実施します。

3 つの AND ブロックが入力 c1、c2、c3 と Constant false を組み合わせ、OR ブロックがそのうち 2 つの結果をまとめます。
リダクション前
1 つの 3 入力の AND ブロックが c1、c2、c3 を組み合わせ、OR ブロックがそれと Constant false をまとめます。
リダクション後

Relational Operator

定数の関係演算子をCompare to Constantブロックに低減します。

Relational Operator ブロックが入力 p を Constant 10 と Constant 0 と比べ、AND ブロックと Switch に渡します。
リダクション前
Compare To Constant ブロックが Constant ブロックなしで p ~= 10 と p >= 0 を判定します。
リダクション後

Saturation & MinMax

このリダクションは一連のブロックをMinMaxブロック、Saturationブロック、またはSaturation Dynamicブロックに置き換えます。 以下に考えられる全てのケースを挙げていきます。

Min

図内で値の最小数を取得するためのロジックを表すブロックの組み合わせを検知し、min関数を用いて、関係しているブロックをMinMaxブロックと置き換えます。

Relational Operator が Constant 5 と入力 dt を比べ、Switch ブロックがどちらかを渡します。
リダクション前
1 つの MinMax ブロックが Constant 5 と dt の min を出力します。
リダクション後
Max

同様に同じロジックを適用して、検知を行い、max関数に低減します。この例では2つ以上の値の最大数を取得するケースを考慮しています。

2 つの Switch ブロックがそれぞれ Relational Operator によって、入力 x と Constant 20、10 から選びます。
リダクション前
1 つの MinMax ブロックが x と Constant 10、20 の max を出力します。
リダクション後
Saturation

事前に定義された2つの値の間の信号の範囲の境界を示すロジックを検索し、関係するブロックをSaturationブロックと置き換えます。

2 つの Switch ブロックがそれぞれ Relational Operator によって、入力 in を Constant 0 と 100 の間に収めます。
リダクション前
1 つの Saturation ブロックが入力 in を制限します。
リダクション後
Saturation Dynamic

2つの動的に与えられた値の間の信号の範囲の境界を示すロジックを同様に検索し、関係するブロックをSaturation Dynamicブロックと置き換えます。

2 つの Switch ブロックがそれぞれ Relational Operator によって、入力 in を入力 lo と hi の間に収めます。
リダクション前
1 つの Saturation Dynamic ブロックが in を lo と hi の間に収めます。
リダクション後

Sum/Product of Element

ベクトルの全ての要素のSumやProduct(要素ごとのSelectorブロックが含まれます)を単一のSumブロック、または、Productブロックに低減します。

全てのSelectorブロックが単一のSumブロックやProductブロックにつなげられる必要があるため、Arithmeticリダクションが有効にされている場合のみ、このリダクションは適用されます。

Sum
3 つの Selector ブロックが入力 array の要素を 1 つずつ選び、Sum ブロックがそれらを足します。
リダクション前
1 つの Sum ブロックが array の要素を足します。
リダクション後
Product
3 つの Selector ブロックが入力 array の要素を 1 つずつ選び、Product ブロックがそれらを掛けます。
リダクション前
1 つの Product ブロックが array の要素を掛け合わせます。
リダクション後

TRUE/FALSE Constants

C言語の定数TRUE/FALSE を持つConstantsを実際のSimulinkのブーリアン型に変更し、一部のその他の最適化を可能にします。以下の例では信号のタイプはint32ではなくブーリアン型であり、NOT Logical Operatorブロックを用いて最適化を適用します。

2 つの Switch ブロックが、入力 a、b と Constant 2 を比べる Relational Operator によって、Constant true と false から選びます。
リダクション前
2 つ目の比較に付けた NOT ブロックが、内側の Switch ブロックとその Constant true と false に代わります。
リダクション後

以下の画像はモデルのサイズを低減するために最適化が適用される別のケースを表しています。

Switch ブロックが p <= 10 を判定する Relational Operator によって Constant true か false を選び、Data Type Conversion ブロックが結果を boolean にします。
リダクション前
Relational Operator による p <= 10 の結果がそのまま return_value に渡ります。
リダクション後

Unary Minus

可能な場合Unary Minusブロックを削除することでモデルを低減します。

Unary Minus ブロックが Constant 2 を 2 回、Constant 1、Constant MAX_VAL の符号を反転してから Product ブロックと Sum ブロックに渡します。
リダクション前
符号の反転が Constant 2、−1、−MAX_VAL に含まれています。
リダクション後

Unit Delay Constant

Unit Delayブロックは静的なローカル変数に対して盛り込まれます。このリダクションにより、これらの変数の動き - つまり、変更可能であり、関数に対する継続的な呼び出しにおいて維持することが可能な初期値を持つ動き – のモデル化が可能になります。

Modelifyは静的なローカル変数が関数本体において変更されていないかどうかを特定します。この場合、Unit Delayブロックは、Unit Delayブロックの初期値を用いて、Constantブロックに置き換えられます。

サンプルの変換のソースコード:

C 言語の関数 redUnitDelayConstant で、インクリメントする static int static_modified と、読むだけの static float static_unmodified があります。

以下の画像は2つのケースを表しています - 修正されていない変数(static_unmodified)と各関数において修正された変数(static_modified)です。

2 つの Unit Delay ブロックが 2 つの static 変数を保持し、1 つは Increment Stored Integer ブロックとのループに、もう 1 つは値を変えるもののないループにあります。
リダクション前
変わらない変数の Unit Delay が Constant 10 になり、インクリメントする変数は Unit Delay のままです。
リダクション後

Vector Assignments

同じベクトル入力が用いられている複数のAssignmentブロックを単一のMuxブロックに低減します。

3 つの Assignment ブロックが続けて、Constant 1 と入力 p1、p2 を 3 つのゼロのベクトルに書き込みます。
リダクション前
1 つの Mux ブロックが Constant 1、p1、p2 をベクトルにまとめます。
リダクション後

Vector Selector

同じベクトル入力が用いられており、入力ベクトルの同じ要素をインデックス付けする複数のSelectorブロックを単一のSelectorブロックに低減します。

5 つの Selector ブロックが入力 array の要素を選び、そのうち 2 つはほかと同じ要素を選んでいます。
リダクション前
要素ごとに 1 つずつの 3 つの Selector ブロックが、Sum ブロック、Relational Operator、Switch に渡します。
リダクション後
目次

ご質問、または修正のご希望はありますか?

どのようなご用件ですか?