# Guy and Seth on Simulink

## Implementing an iterative algorithm using the While Iterator Subsystem

Last week I helped a user implementing an iterative algorithm in Simulink using the While Iterator Subsystem. I thought it would be interesting to share this technique.

Example Iterative Algorithm

An iterative algorithm is an algorithm that, when called multiple times, converges toward a more and more accurate solution.

A well known example of this is the Babylonian method of computing square roots.

For example, using this method the following script takes about 10 iterations to compute the square root of 900 with an error less than 1e-6.

Typically, in Simulink, blocks are executed once per time step (it is not always true, but let's assume that for today). For example, if I implement the equations above at the top level of a model with a fixed step solver and a sample time of 1 second, it will take ten seconds of simulation before the algorithm converges:

As you can see, for a constant input, the algorithm slowly converges. But what if the input changes constantly? And what about the first steps where the answer is wrong?

We clearly need the algorithm to iterate multiple times at the same time step. To do that, you need an Iterator Subsystem:

With this implementation, at every step you will get an answer within the specified tolerance.

Starting with results for the previous step

In the implementation above, if we start the search with an initial guess of 1 every step, this is not very efficient. To help with that, you can start the search with the result of the previous time step by configuring the While Iterator Subsystem to hold its state:

Of course, I do not recommend using this algorithm to compute the square root of a Signal in Simulink. The Square Root block is more optimized than the above approach.

I hope this gives you an overview of the concept. Let us know if you use the While Iterator Subsystem to implement iterative algorithms by leaving a comment here

### 7 Responses to “Implementing an iterative algorithm using the While Iterator Subsystem”

1. KMR replied on :

I’ve used this kind of thing before, but one potential problem is if this is in a reference model and you want to save output using signal logging: how do you save values at intermediate stages of the iteration? I haven’t figured out a solution to that one.

2. Guy Rouleau replied on :

@KMR: The “dataset” format for logging saves all the iterations. I just verified and this works for referenced models, both in normal and accelerated mode.

You can find an example in this post:

http://blogs.mathworks.com/seth/2011/08/22/the-dataset-logging-format/

3. Paul replied on :

Guy,

The very first sentence of the doc page for the Memory block says “The Memory block holds and delays its input by one integration time step.” This statement clearly does not apply in your use case. There are other aspects of this block that are inconsistent with this statement as well. For example, the Memory block can inherit a discrete sample time, in which case it is “is analogous to the Unit Delay block.” Also, I suspect the doc page should really say “one major integration time step” when it’s actually used in that way. I’m not sure if the doc page even alludes to the While Iterator use case. That doc page needs to be scrubbed.

Are there any other blocks with a “state” that can ever be used in a While Iterator system? I can’t envision what it would even mean to include an Integrator or Discrete Filter in such a subsystem. From what I can see, the While Iterator subsystem is Atomic (though the sample time can only be inherited for some reason) so I guess including a continuous block, like an Integrator, throws an error. There is also discussion about simplified initialization mode relative to this question, but it suggests that if not using a simplified initialization mode then it can contain a Discrete Filter, in which case I guess that the filter would advance by one iteration every time through the loop? If that’s the case, that needs to be explained better in the doc for the Discrete Filter and in the doc for the While Iterator. But I’m still curious as to examples where that kind of capability is needed.

4. Guy Rouleau replied on :

@Paul: Thank you for detailed comment.

I agree that the documentation for the Memory block does not cover the Iterator Subsystems cases. I contacted our documentation page so this can be improved.

You can see the iterator subsystems as function-call subsystems that are triggered more than once per time step. They only support blocks configured to inherit their sample time.

This means that blocks with continuous states cannot be used in such subsystem. One interesting thing is that blocks with discrete states will update their states every iteration, not every time step. As you mention, the behavior of blocks like Discrete Filter and Discrete State-Space inside an iterator subsystem can be surprising, and I cannot think of a use case right now.

About Simplified initialization mode, you are right that it changes the list of blocks that can be used inside iterator subsystem. For example the Discrete Time Integrator cannot be used in an iterator subsystem when using simplified initialization model. The error message you receive if you try explains that this is because time is not well defined in such subsystem.

5. Melih replied on :

Hello Guy,

I’m trying to implement an iterative algorithm using while iterator subsystem. My problem is that initial value is supplied from outside the while iterator subsystem, so I used the DELAY block with initial value given via an input port. The initial value is changing because the while iterator lies in a for each subsystem to use the algoritm with several different initial values. When I generated code, I discovered that the delay block is initialized in the while loop using an if else statement, which causes an inefficiency by checking the initial value at every iteration. This behaviour is always observed when using a delay block with an initial value via input port, even if the while iterator subsystem does not reside in an other iterator. Is there any way that the starting value is defined outside the loop in the generated code? Or do I ask something infeasible or impossible?

6. Guy Rouleau replied on :

@Melih: This is an interesting use case. I tried reproducing what you describe, but I am not sure I grasp everything.

Inside the while loop, I can see an IF statement to pass the initial value at the first iteration and the state for all others. This if statement does check the initial value every step, but uses a temp uint8 variable.

If I change the while for a do-while, then the IF statement is done before the while loop.

I don’t think there is a way to remove the IF some the while loop, but I would recommend contacting technical support with an example model to be 100% sure.

7. Melih replied on :

@Guy: I can imagine that, it is very difficult to help without an example model. I should have been more specific and more accurate. Indeed, you are right about the checking the value of the temp uint8 variable (I described my problem inaccurately). What I wanted to point out, was that this ‘if’ statement is unneccessary in my case. Because I don’t need to change the value of the state to its initial value during the iteration in the while loop. As you described in your blog, we can let the while iterator to hold or to reset the value of the state before it starts iterating. Thank you very much for your effort. I will contact the technical support to get further assistance.

 Name (required) E-mail (required, will not be published) Website (optional) Spam protection (required): What is 9 + 10 ?

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>


If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).

Guy Rouleau and Seth Popinchalk are Application Engineers for MathWorks. They write here about Simulink and other MathWorks tools used in Model-Based Design.

These postings are the author's and don't necessarily represent the opinions of MathWorks.