0

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.

1
  • 3
    You defined it as theta0_ and call it as theta0. Also, you don't need to call it through handle. Commented Aug 31, 2013 at 16:46

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Hi there, thanks for the detailed reply. Few questions, what do you mean by indirection? Do you mean that I can call the functions from F_ using their function names (theta0_ and theta1_) and not have to use function handles (theta0 and theta1)? Maybe I just don't get global variables, but for my work now, there are variables in the base workspace that I want these functions to use without having to pass them into the function e.g. df0dt a0 f0 SigmaRF. Is the way I've done in in my theta functions correct?
The global declarations look good, but you also have to declare them as global in your base workspace. Or you could use df0dt=evalin('base','df0dt'); in your functions to access the base workspace. By indirection I mean the direct way to call theta0_ is to type in theta0_. If you don't know beforehand what function you have to call, you can add a level of indirection: You declare a function handle and set it to the correct function, and at the call site you call the function the handle points to. This is what you have done with theta0 which refers to theta0_ but can be changed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.