2
votes

I hope this is the right area. I'm trying to get this code to work in MatLab.

function y=test(x)
    y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r-  a)+p* ((b/x)^B))/(1-(b/x)^B);
end

I then jump to the command value and type this:

B=3.0515;
b=1.18632*10^5;
a=.017;
r=.054;
p=5931617;

I then try to find the zeros of the first equation by typing this and I get errors:

solution=fzero(@test,5000000)

I'm getting the following error:

Error: File: test.m Line: 5 Column: 1 This statement is not inside any function. (It follows the END that terminates the definition of the function "test".)

New error

Error using fzero (line 289) FZERO cannot continue because user supplied function_handle ==> @(x) (test(x,B,b,a,r,p)) failed with the error below.

Subscript indices must either be real positive integers or logicals.

2
Welcome to SO, please edit your question to include the verbatim error message that you received. ALWAYS include the exact error you get in your question. But also, if you are defining B, b, a etc in the commend line, they will not have scope in your function test. So as far as test is concerned they are essentially undefined. - Dan

2 Answers

1
votes

I would guess that this is a problem of scoping, you are defining variables (B, b, etc...) in the command line but trying to use them inside your test function where they are out of scope. You should alter your test function to take these in as parameters and then use an anonymous function so that your call to test in fsolve still only takes a single parameter:

function y=test(x, B, b, r, a, p)
    y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r-  a)+p* ((b/x)^B))/(1-(b/x)^B);
end

and

B=3.0515;
b=1.18632*10^5;
a=.017;
r=.054;
p=5931617;

solution=fzero(@(x)(test(x,B,b,a,r,p)),5000000)

As an aside, unless you really do mean matrix multiplication, I would suggest that you replace all your *s and /s in test with the element-wise operators .* and ./. If you are dealing with scalars, it doesn't matter now, but it makes a big difference if you later want to scale your project and need a vectorized solution.

Regarding the errors you have added to your question:

  1. You can't put code after the end in your function file. (With the exception of local functions). Your objective function should be an .m-file containing the code for one single function.
  2. This is because in your test function you have ...b((1-(b/x)^(B-1))... which in MATLAB means you are trying to index the variable b in which case the value of (1-(b/x)^(B-1) has to be a positive integer. I'm guess you are missing a *
0
votes

Your

function y=test(x)
    y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r-  a)+p* ((b/x)^B))/(1-(b/x)^B);
end

cannot access variables in your workspace. You need to pass the values in somehow. You could do something like:

function y=test(x,B,b,a,r,p)
    y=-x+(B/(B-1))*(r-a)*p+(B/(B-1))*(r-a)*(b((1-(b/x)^(B-1))/r-  a)+p* ((b/x)^B))/(1-(b/x)^B);
end

and then you can create an implicit wrapper function:

B=3.0515;
b=1.18632*10^5;
a=.017;
r=.054;
p=5931617;
solution = fzero(@(x) test(x,B,b,a,r,p),5000000)

I haven't tested whether fzero returns sensible results, but this code shouldn't give an error.