Main Content

Using Conditional Expressions in Equations

You can specify conditional expressions in equations or conditional assignments to intermediates by using if and .if statements. In an if statement, predicates must be scalar. To evaluate array-type predicates, use .if statements.

if Statement Syntax

You can specify conditional equations by using if statements.

equations
  [...]
  if PredicateExpression1
    [...] % if branch equations
  elseif PredicateExpression2
    [...] % elseif branch equations
  else
    [...] % else branch equations
  end
  [...]
end

Each [...] section contains one or more equation expressions.

The if and elseif branches start with a predicate expression. If a predicate is true, the equations in that branch get activated. When all predicates are false, the equations in the else branch get activated.

You can nest if statements, for example:

equations
  [...]
  if PredicateExpression1
    [...] 
    if PredicateExpression2
       [...]
    else
    [...]
    end
  else
    [...]
  end
  [...]
end

In this example, the second predicate expression gets evaluated only if the first predicate is true.

Rules and Restrictions

  • Every if requires an else.

  • The total number of equation expressions, their dimensionality, and their order must be the same for every branch of the if-elseif-else statement. However, this rule does not apply to the assert expressions, because they are not included in the expression count for the branch.

Example

For a component where x and y are declared as 1x1 variables, specify the following piecewise equation:

y={xfor 1<= x<=1x2otherwise 

This equation, written in the Simscape™ language, would look like:

equations
  if x >= -1 && x <= 1
    y == x;
  else
    y == x^2;
  end
end

Another way to write this equation in the Simscape language is:

equations
  y == if x>=-1 && x<=1, x else x^2 end
end

Array-Type Conditional Predicates

You can perform element-wise conditional operations with array-type predicates by using .if statements. For example:

component my_comp
inputs
  pred1 = [1 0 0];
  pred2 = [0 0 1];
end
parameters
    A = [1 2 3];
    B = [4 5 6];
    C = [7 8 9];
end
intermediates
    y = .if pred1, A; .elseif pred2, B; .else C; .end
end
... % Other parameters, variables, equations
end

With these input values, the intermediate y evaluates to [1 8 6] because:

  • The first element of pred1 is true, so the first value is the first element of parameter A

  • The second element of neither pred1 or pred2 is true, so the second value is the second element of parameter C

  • The third element of pred2 is true, so the third value is the third element of parameter B

Rules and Restrictions

  • Every .if requires an .else.

  • .elseif branches are optional. Any subsequent .elseif branch must have a predicate of the same size and shape as the original .if branch predicate.

  • Each branch of the .if-.elseif-.else statement must match the size and shape of the predicates. Scalar expansion applies.

    Whether scalar expansion is necessary is determined on a branch-by-branch basis, so using an array in one branch and a scalar in another is allowed.

  • Units must be commensurate between branches.

  • Terminate an .if statement with the .end keyword.

  • Output is an array of the same size and shape as the .if branch predicate. For multiple return values, each output variable is the same size and shape as the predicate.

Array-type predicates are not supported for:

  • Conditional sections

  • Mode charts

  • Assert statements

Example

This component represents a vectorized saturation block:

component vec_saturation
    inputs
        I = zeros([3 3]);
    end
 
    outputs
        ITrue = zeros(size(I));
    end
 
    parameters
        upper_limit = 5;
        lower_limit = 0.7;
    end
 
    equations
        ITrue == .if I>=upper_limit, upper_limit; 
                 .elseif I <= lower_limit, lower_limit; 
                 .else I; 
                 .end
    end
end

See Also

|

Related Topics