if loop inside matlab function ----- i dont understand why this is not working

function y = fcn(u)
if(u>0.7) && (u<0.71)
y=1;
end
It gives error when put inside my simulink simulation:
Output argument 'y' is not assigned on some execution paths.
Function 'MATLAB Function' (#38.9.10), line 1, column 10:
"y"
Launch diagnostic report.
Component:MATLAB Function | Category:Coder error
Errors occurred during parsing of MATLAB function 'MATLAB Function'

11 Comments

Hi.
This is just an idea but your error sounds like that there is just missing an else path with y=0 to tell simulink what to do in every possible case.
Just try...
I want to latch that event...so y=1 thereafter...and hence no else...or is there a better way to do it..
You could initialise y=0 before your if loop. Then it shouöd work i guess.
function y =fcn(u) 
  y = 0;
  if(u>0.7) && (u<0.71)
    y=1;
  end

Try this

I think it has to be initialized in the function

The above rewrite works but I'd suggest

function y =fcn(u) 
  y = u>0.7 & u<0.71;
end

NB: If the argument u is not a scalar then the result will probably never be true; the result of an logical operation on a vector or array is also a vector or array of the same size and if is true IFF all elements of the vector are true

The ML editor probably flagged (with the orange line in RH margin) about the use of && for scalar as well...

error is not there, but my purpose was to latch. That's not hppening.
function y = fcn(u)
y=0;
if(u>0.7) && (u<0.71) && y=0
y=1;
end
This could help to latch i guess
function y = fcn(u)
y=0;
if ((u>0.7) && (u<0.71) && y=0)
y=1;
end
I am getting the following error: Simulink cannot determine sizes and/or types of the outputs for block 'MATLAB Function' due to errors in the block body, or limitations of the underlying analysis. The errors might be inaccurate. Fix the indicated errors, or explicitly specify sizes and/or types for all block outputs.

Sign in to comment.

Answers (1)

Here is a event based solution to latch the value. The solution use if block and if action subsystem to latch the output once a certain condition is met. I used the clock as the input and the if condition becomes true between 20 to 21 seconds but output remains 1 after 20 seconds.

The Simulink model file is also attached.

13 Comments

I wondered when I saw "latch" in the second comment if that might not have been OP's purpose.

"... is not possible with MATLAB function block."

While I'd never recommend for the purpose with Simulink, it is possible with Matlab by using persistent to retain state between function calls

I didn’t knew about persistent. Thanks for correction.

Hi dpb,

i want to be sure that i understood correct. The following code would work for this purpose and also would latch the value for y between the several functions calls, but is not recommended for use in Simulink?

function y = myfun(u)
persistent value
      if(u>0.7) && (u<0.71)
          value=1;
      end
      y = value;
end

Is there any reason why it should not be used this way?

best regards

Stephan

That won't latch if that's the purpose, no...as coded it will still return the value based only on the input value of u; the persistent value isn't used to determine whether or not to reset its value.

CLARIFICATION It will latch if the condition on u is satisfied, that is true; it will fail on first call for lack of value being assigned; that it has been declared persistent will keep from generating an undefined error but the function will return empty which likely will cause an error in the calling routine expecting a value.

The function would also have to be called to initialize the persistent variable first before use.

If one had need for such a function in Matlab base product that would be the way to implement it; in Simulink there's better ways given its manner of operation.

I was simply pointing out that there is (and doc says before R2006 altho I didn't think it had been that long) the facility in ML.

One (unoptimized) implementation...

function y = myfun(u,init)
  persistent value
  if nargin==2
    value=0;
    y=value;
    return
  end
  if value==1
    y=value;
    return
  end
  if u>0.7 & u<0.71
    value=1;
    y=value;
  end
end
What is init in the code...it is not used at all
Call that code with two parameters to force the output to be re-initialized to 0. The value of the second parameter does not matter, it just has to be two parameters.
However, this is not likely to be convenient to call with multiple parameters in Simulink.
For Simulink, you could use something like
function y = myfun(u)
persistent value
if isempty(value)
value = 0;
end
if u>0.7 & u<0.71
value = 1;
end
y = value;
This will only initialize the first time the block is run, and will not reinitialize unless some kind of clear is done such as if the model is unloaded.
You generally want more control over when the function will be reinitialized, so you would generally instead use a function block with two inputs, one of which controls reinitialization.
function y = myfun(u, init)
persistent value
if init
value = 0;
end
if u>0.7 & u<0.71
value = 1;
end
y = value;
This needs two inputs rather than one. The second input should be non-zero if you want to reinitialize, and should be 0 if you want to keep the current state. This differs from the use of init that dpb proposed in that dpb's proposal required that the function be called in different ways depending on what you wanted to do, which is a problem in Simulink.
function y = myfun(u, init)
persistent value
if init
value = 0;
end
if u>0.7 & u<0.71
value = 1;
end
y = value;
init = 0 , getting error: Function 'MATLAB Function' (#120.125.130), line 9, column 7: "value" Launch diagnostic report. Component:MATLAB Function | Category:Coder error Errors occurred during parsing of MATLAB function 'MATLAB Function' Component:MATLAB Function | Category:Coder error
You could try
function y = myfun(u, init)
persistent value
if isempty(value)
value = 0;
end
if init
value = 0;
end
if u>0.7 & u<0.71
value = 1;
end
y = value;
Reduce the number of if statements (optional init too):
function y = myfun(u, init)
persistent value
if isempty(value) || (nargin>1 && init)
value = 0;
end
if u>0.7 & u<0.71
value = 1;
end
y = value;
end
Making init optional is not feasible for Simulink use. You would need to disable a port by disconnecting it, or you would need to use enabled subsystems that turned off an input (and I do not know how Simulink is defined to behave in that case.)
Once placed and connected, any one Simulink block is expected to always be called with the same number of inputs.
Thanks a lot, Roberson and all others who contributed to the discussion. Now, it is doing what it is supposed to do !!

Sign in to comment.

Categories

Products

Asked:

on 22 Apr 2018

Edited:

on 8 Sep 2018

Community Treasure Hunt

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

Start Hunting!