How to break FOR loop in simulink

20 次查看(过去 30 天)
minhkiyo
minhkiyo 2021-11-17
评论: yicong 2024-9-6
Hi,
In Simulink, I have a signal that is a 1-D array.
I want to get the index of the first value other than 0, but the result received is the index of the last non-zero value
I am new to Simulink, is there any way to break FOR loop?
Or what should I do in this case
Any hint will be great.
Thanks.

回答(2 个)

Rajanya
Rajanya 2024-9-5
I understand that you want to implement a break logic in the ‘for iterator’ subsystem in Simulink.
Although the subsystem does not provide any direct control for conditional loop exit, you can modify the ‘for iterator’ block parameter and tick the ‘Set next_i externally’ option. This allows you to have control over your iteration variable and implementing break now would be similar to setting the ‘Next_i’ to the length of the array, ensuring the loop stops in the next iteration.
This can be implemented using a switch block which would increment ‘i’ if the condition is not met and directly set ‘i’ to the array’s length if the condition is met. The below diagram shows a sample implementation of the same.
Hope this helps.

Yash
Yash 2024-9-5
编辑:Yash 2024-9-5
Hi Minhkiyo,
There are multiple solutions possible to resolve this issue:
1. While Iterator block
Instead of using a "For Iterator" block, you should use a "While Iterator" block. You can connect the output of the "Compare to Zero" block to the "cond" port of the "While Iterator" block using a "NOT" block in between to stop the iteration once the non zero element is found.
You need to keep a check on the following points:
  1. You must check the "Show iteration number port" in the block parameters of the "While Iterator" block to use the index.
  2. You should change the maximum number of iterations accordingly. Since it cannot be taken as an input signal, you need to enter this in the block parameters. One better way to handle this issue is to enter -1 in the block parameters and handle the array size in the "cond" port. The new condition for the while loop will be (i<N && in_array[i]==0).
Here is the image for the correct model:
2. MATLAB Function Block
You can use a MATLAB function block which takes the array and its size as input and returns the index as output. Here is code for the same:
function index = findFirstNonZero(array, arraySize)
index = -1;
for i = 1:arraySize
if array(i) ~= 0
index = i;
break;
end
end
end
3. Reverse the array
Since you model gives the the index of last 1, you can reverse the array at the input side and get the index of the first 1.
I hope this helps!
  1 个评论
yicong
yicong 2024-9-6
R1 = 6.3;
R2 = 6.3;
R3 = 6.3;
tau1 = 1e-5;
tau2 = 1e-2;
tau3 = 1e1;
t_min = 1e-6;
t_max = 1e2;
num_points_per_decade = 20;
num_decades = log10(t_max) - log10(t_min);
num_points = round(num_points_per_decade * num_decades);
t_interp = logspace(log10(t_min), log10(t_max), num_points);
z_interp = log(t_interp);
a_t = R1 * (1 - exp(-exp(log(t_interp))/tau1)) + ...
R2 * (1 - exp(-exp(log(t_interp))/tau2)) + ...
R3 * (1 - exp(-exp(log(t_interp))/tau3));
da_dz = gradient(a_t, z_interp);
% W(z) = exp(z - exp(z))
W_z = exp(z_interp - exp(z_interp));
max_iterations = 100;
Psi_z = da_dz;
w=W_z';
a=da_dz';
for iter = 1:1:max_iterations
R1=Psi_z*(corr(w, a./(conv(w,Psi_z,'same'))));
Psi_z=R1;
end
R_final = Psi_z;
figure;
subplot(3,1,1);
plot(z_interp, da_dz);
title('da/dz vs z');
xlabel('z');
ylabel('da/dz');
subplot(3,1,2);
plot(z_interp, W_z);
title('W(z)');
xlabel('z');
ylabel('W(z)');
subplot(3,1,3);
plot(z_interp, Psi_z);
title('\Psi(z) after Van Cittert Deconvolution');
xlabel('z');
ylabel('\Psi(z)');
The code runs wrong. Sorry I apply your code in the same iteration from that picture of deconvolution form. Could you help me to find where I make the mistake?

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Loops and Conditional Statements 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by