Fayyaadh
Fayyaadh

Reputation: 57

Calling a function from inside another function?

I have 3 short functions that I've written inside 3 separate m files in Matlab.

The main function is called F_ and accepts one input argument and returns a vector with 3 elements.

Element 1 and 2 of the output from F_ are (supposed to be) calculated using the functions in the other 2 m files, lets call them theta0_ and theta1_ for now.

Here's the code:

function Output = F_(t)

global RhoRF SigmaRF

Output = zeros(3,1);

Output(1) = theta0(t);
Output(2) = theta1(t) - RhoRF(2,3)*sqrt(SigmaRF(2,2))*sqrt(SigmaRF(3,3));
Output(3) = -0.5*SigmaRF(3,3);

end

and

function Output = theta0_(t)

global df0dt a0 f0 SigmaRF

Output = df0dt(t) + a0 + f0(t) + SigmaRF(1,1)/(2*a0)*(1-exp(-2*a0*t));

end

and

function Output = theta1_(t)

global df1dt a1 f1 SigmaRF

Output = df1dt(t) + a1 + f1(t) + SigmaRF(2,2)/(2*a1)*(1-exp(-2*a1*t));

end

I've created handles to these functions as follows:

F = @F_;
theta0 = @theta0_;
theta1 = @theta1_;

When I run F_ via it's handle with any value of t I get the following error:

F_(1)
Undefined function 'theta0' for input arguments of type 'double'.

Error in F_ (line 9)
Output(1) = theta0(t);

Please assist. What am I doing wrong here?

I only want to be able to call one function from within another.

Upvotes: 0

Views: 8232

Answers (1)

mars
mars

Reputation: 804

Each function has its own workspace, and since you didn't create theta0 inside the workspace of function F_ you get an error.

Chances are that you don't need that extra level of indirection and you can use theta0_ in your function.

If you do need that extra level of indirection, you have several options:

  • Pass the function handle as an argument:

    function Output = F_ ( t, theta0, theta1 )
        % insert your original code here
    end
    
  • Make F_ a nested function:

    function myscript(x)
    
    % There must be some reason not to call theta0_ directly:
    if ( x == 1 )
        theta0=@theta0_;
        theta1=@theta1_;
    else
        theta0=@otherfunction_;
        theta1=@otherfunction_;
    end
    
        function Output = F_(t)
            Output(1) = theta0(t);
            Output(2) = theta1(t);
        end % function F_
    
    end % function myscript
    
  • Make the function handles global. You must do that both in F_ and where you set theta0 and theta1. And make sure that you don't use global variables with the same name somewhere else in your programm for something different.

    % in the calling function:
    global theta0
    global theta1
    
    % Clear what is left from the last program run, just to be extra safe:
    theta0=[]; theta1=[];
    
    % There must be some reason not to call theta0_ directly.
    if ( x == 1 )
        theta0=@theta0_;
        theta1=@theta1_;
    else
        theta0=@otherfunction_;
    end
    
    F_(1);
    
    % in F_.m:
    function Output = F_(t)
        global theta0
        global theta1
        Output(1)=theta0(t);
    end
    
  • use evalin('caller', 'theta0') from inside F_. That might lead to problems if you call F_ from somewhere else, where theta0 is not declared or even used for something different.

Upvotes: 2

Related Questions