Does Simulink and Matlab has different compiler for user defined functions?

I wrote a function in Matlab and it works just fine. When I put it in the Simulink User defined block Matlab fcn it does not work. Simulin returns error on array mismatch.
function G = my_fcn(X)
nule = zerocros(X);
k = size(nule);
n = 1;
i = 0;
G = [];
for i=1:k(1,1)
if i + 10 > k(1,1)
break
end
Y = nule(i:i+10);
if Y(11) > 10
G(:,n) = Y - Y(1);
G(:,n) = G(:,n)./G(11,n);
G(1,n) = nule(i);
G(11,n) = Y(11);
n = n + 1;
end
end
Simulink returns:
Index exceeds matrix dimensions. The array G is empty and therefore has no valid indices. Error in 'za_simulink_zerocross/MATLAB Function' (line 13) G(:,n) = Y - Y(1);
("Y" is one dimensional array and its size is always 11.)
Matlab returns nothing and function works. 1. What is the difference in Matlab vs Simulink fcn? 2. How to define some kind of flexible array that can increment number of columns.
Best

 採用された回答

Birdman
Birdman 2018 年 1 月 3 日
This is the main property of Simulink. If you write a function yourself, you need to define the size of output at the very beginning of the function. The error comes from that you define G empty, in which Simulink will think that its size is fixed and won't change during the simulation. Therefore, you need to preallocate some space for your output G. Consider the following approach:
function G = my_fcn(X)
G = zeros(11,1);
nule = zerocros(X);
k = size(nule);
n = 1;
i = 0;
for i=1:k(1,1)
if i + 10 > k(1,1)
break
end
Y = nule(i:i+10);
if Y(11) > 10
G(:,n) = Y - Y(1);
G(:,n) = G(:,n)./G(11,n);
G(1,n) = nule(i);
G(11,n) = Y(11);
n = n + 1;
end
end
At the very beginning, I told Simulink that output G is going to be a column vector which has 11 rows. If you try to create new row during the simulation, it will throw an error, therefore always be careful to stay within predefined sizes.

14 件のコメント

Zeljko Tomicevic
Zeljko Tomicevic 2018 年 1 月 3 日
Thanks for answer.
Not works, it returns:
Index exceeds array dimensions. Index value 2 exceeds valid range [1-1] of array G. Error in 'za_simulink_zerocross/MATLAB Function' (line 13) G(:,n) = Y - Y(1);
Birdman
Birdman 2018 年 1 月 3 日
編集済み: Birdman 2018 年 1 月 3 日
G(:,n) = Y - Y(1);
G is a column vector and Y is a row vector. Define G at the beginning as follows:
G = zeros(1,11);
Now it is a row vector. Also change the error line to
G(n,:) = Y - Y(1);
Also:
G(n,:) = G(n,:)./G(n,11);
G(n,1) = nule(i);
G(n,11) = Y(11);
The following line is a danger since you increase the siz of G dynamically. It will cause error.
n = n + 1;
Zeljko Tomicevic
Zeljko Tomicevic 2018 年 1 月 3 日
Nither
Index exceeds array dimensions. Index value 2 exceeds valid range [1-1] of array G. Error in 'za_simulink_zerocross/MATLAB Function' (line 13) G(n,:) = Y - Y(1);
We only switched everything with this solution. Mine first function (the one in the my first question here) works fine in Matlab, so why not in Simulink?
Birdman
Birdman 2018 年 1 月 3 日
I will deal with it at evening, but I need the model and all other necessary stuff with it.
Zeljko Tomicevic
Zeljko Tomicevic 2018 年 1 月 3 日
I can not know how many columns output G will have. I have defined G as Variable output in Model Explorer.
Birdman
Birdman 2018 年 1 月 3 日
No, change it to fixed output because in code you define its size.
Zeljko Tomicevic
Zeljko Tomicevic 2018 年 1 月 3 日
How can I send it to you?
Birdman
Birdman 2018 年 1 月 3 日
Save it in mdl format and send it in comment.
Zeljko Tomicevic
Zeljko Tomicevic 2018 年 1 月 3 日
Birdman
Birdman 2018 年 1 月 4 日
Can you also share the .wav file?
Zeljko Tomicevic
Zeljko Tomicevic 2018 年 1 月 4 日
I can not upload .wav here, does not accept. You can use any .wav (there should be audio input). This one can be found in C:\Program Files\MATLAB\R2017b\toolbox\audio\samples\Click-16-44p1-mono-0.2secs.wav
Birdman
Birdman 2018 年 1 月 4 日
I somehow managed to fix the dimension error. It is always best to preallocate huge size for the output but your output data has some problems. Hope you can solve it but you will not receive any dimension error. Do not play with the sizes anymore.
Zeljko Tomicevic
Zeljko Tomicevic 2018 年 1 月 4 日
Thanks, but this is not solution. The G array has to have column 11 long. G array going to the Neural network after, and NN reads column by column. This is just oversized array. There must be solution to increment column number in the array in Simulink like there is in Matlab. In Matlab that works perfect. Thank you very much. You put a lot of effort to help me.
Birdman
Birdman 2018 年 1 月 4 日
編集済み: Birdman 2018 年 1 月 4 日
How about I give you only the numerical values and you choose which ones to use in your calculation? You can create your own 11 column array by some manipulations. Use the following code after you run the simulation in command line:
a=simout.signals.values;
a=unique(a(isnumeric(a) & ~isnan(a) & a~=0)).'

サインインしてコメントする。

その他の回答 (1 件)

Zeljko Tomicevic
Zeljko Tomicevic 2018 年 1 月 12 日

0 投票

Matlab help said that it should not be done in code since allocating of memory for array widening is time consuming and should be avoided. I have concluded that Matlab has better stomach than Simulink for inexperienced users.

1 件のコメント

Birdman
Birdman 2018 年 1 月 12 日
It depends on how you look at things. On the other hand, Simulink offers so much different toolboxes ready to be used. On MATLAB, you need to write the code to say the least. But anyway, do your thing how you find easy.

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeSimulink についてさらに検索

質問済み:

2018 年 1 月 3 日

コメント済み:

2018 年 1 月 12 日

Community Treasure Hunt

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

Start Hunting!

Translated by