Fail Analysis
Fail Analysis

Reputation: 143

Octave call a function as a variable of another function

I wrote a bisection method in Octave but it can't consume another function..

My bisection method code is like:

function[x,b] = bisection(f,a,b)

  t = 10e-8

  while abs(b-a) > t;
    c = (a+b)/2;

    if f(a) * f(b) <= 0
       a = a;
       b = c;
    else 
       b = b;
       a = c
    endif
  endwhile

  x = (a+b)/2
endfunction

And I already have a file f1.m:

function y = f1(x)
  y = x^2 - 4;
endfunction

But when I call [x,v] = bisection[f1,0,5], I get:

>> [t,v] = bisection(f1,0,5)
   error: 'x' undefined near line 2 column 5
   error: called from
          f1 at line 2 column 3
   error: evaluating argument list element number 1

Upvotes: 4

Views: 7805

Answers (2)

Tasos Papastylianou
Tasos Papastylianou

Reputation: 22215

Andy has given you the answer on how to fix this. I would just like to add why you get that error and what it means. Consider the following octave session:

octave:1> function Out = g1(x); Out = x+5; end
octave:2> function Out = g2(); Out = 10;end
octave:3> 
octave:3> g2
ans =  10
octave:4> g1
error: 'x' undefined near line 1 column 29
error: called from
    g1 at line 1 column 27

I.e., when you write g1 or g2 here, this is an actual function call. The call to g2 succeeds because g2 does not take any arguments; the syntax g2 is essentially equivalent to g2(). However, the call to g1 fails, because g1 expects an argument, and we didn't provide one.

Compare with:

octave:4> a = @g1;
octave:5> b = @g2;
octave:6> a
a = @g1
octave:7> a(1)
ans =  6
octave:8> b
b = @g2
octave:9> b()
ans =  10

where you have created handles to these functions, which you can capture into variables, and pass them as arguments into functions. These handles could then be called as a(5) or b() inside the function that received them as arguments, and it would be like calling the original g1 and g2 functions.

When you called bisection(f1,0,5), you essentially called bisection(f1(),0,5), i.e. you asked octave to evaluate the function f1 without passing any arguments, and use the result as the first input argument to the bisection function. Since function f1 is defined to take an input argument and you didn't supply any, octave complains that when it tries to evaluate y = x^2 - 4; as per the definition of f1, x was not passed as an input argument and was therefore undefined.

Therefore, to pass a "function" as an arbitrary argument that can be called inside your bisection function, you need to pass a function handle instead, which can be created using the @f1 syntax. Read up on "anonymous functions" on the octave (or matlab) documentation.

Upvotes: 4

Andy
Andy

Reputation: 8091

what you want is to pass a pointer to f1 to your function bisection so the right call would be

[t,v] = bisection(@f1,0,5)

which outputs:

t =    1.0000e-07
a =  0.62500
a =  0.93750
a =  1.0938
a =  1.1719
a =  1.2109
a =  1.2305
a =  1.2402
a =  1.2451
a =  1.2476
a =  1.2488
a =  1.2494
a =  1.2497
a =  1.2498
a =  1.2499
a =  1.2500
a =  1.2500
a =  1.2500
a =  1.2500
a =  1.2500
a =  1.2500
a =  1.2500
a =  1.2500
a =  1.2500
a =  1.2500
x =  1.2500
t =  1.2500
v =  1.2500

Upvotes: 5

Related Questions