# Solving an equation in matlab

I would like to solve the equation:

1/2*logninv(x, 0.03-1/2*0.2^2 + log(100), 0.2^2) +1/2*logninv(x, 0.03-1/2*0.1^2 + log(100), 0.1^2) == 100


I can solve this using excel with the solver, but I'm trying to solve it with matlab, I use the code:

vpasolve(1/2*logninv(x, 0.03-1/2*0.2^2 + log(100), 0.2^2) +1/2*logninv(x, 0.03-1/2*0.1^2 + log(100), 0.1^2) == 100,x,0.24)


but this gives me following error:

Error using symfun>validateArgNames (line 175)
Second input must be a scalar or vector of unique symbolic variables.

Error in symfun (line 42)
y.vars = validateArgNames(inputs);

Error in sym/subsasgn (line 1452)
C = symfun(B,[inds{:}]);

Error in logninv (line 60)
p(p < 0 | 1 < p) = NaN;


from which I deduce that I need to tell matlab that x must be between 0 and 1 so then I use:

vpasolve(1/2*logninv(x, 0.03-1/2*0.2^2 + log(100), 0.2^2) +1/2*logninv(x, 0.03-1/2*0.1^2 + log(100), 0.1^2) == 100,x<1,x>0,[x])


but this gives me the error:

Error using symfun>validateArgNames (line 175)
Second input must be a scalar or vector of unique symbolic variables.

Error in symfun (line 42)
y.vars = validateArgNames(inputs);

Error in sym/subsasgn (line 1452)
C = symfun(B,[inds{:}]);

Error in logninv (line 60)
p(p < 0 | 1 < p) = NaN;

• How do you deduce that? The error message says "Second input must be a scalar or vector of unique symbolic variables." – A. Donda May 7 '15 at 16:58
• And your second syntax is not correct. To pass multiple equations, make a vector of equations. – A. Donda May 7 '15 at 17:17
• I thought "p(p < 0 | 1 < p)" meant this.. – Holymonk May 7 '15 at 17:39
• Maybe you are right. I fiddled around a bit, but couldn't find a solution. Do you need VPA? – A. Donda May 7 '15 at 17:59
• Ok, I found that that line makes a problem because at one point p is not a numeric array but a symbol. I suspect logninv is not compatible with symbolic computation, and therefore with vpasolve. Again, do you need VPA, or would a standard-precision numerical estimate be OK too? – A. Donda May 7 '15 at 18:20

You want to find the position within an interval at which a function attains a specific value. This can be framed as an optimization problem: Where is the deviation of the function value from the specific value minimal? Since the variable is bounded to an interval, we can use fminbnd from the Optimization Toolbox.

Define the function:

fun = @(x)(1/2*logninv(x, 0.03-1/2*0.2^2 + log(100), 0.2^2) +1/2*logninv(x, 0.03-1/2*0.1^2 + log(100), 0.1^2));


Define a function that computes the deviation or error:

err = @(x)(abs(fun(x) - 100));


Solve the optimization problem:

x = fminbnd(err, 0, 1)


The result is 0.23993814958158.

Let's check whether the error could be brought down to zero:

err(x)


The result is 0.000121288471035541. Considering that the function value goes from 0 at 0 to 110 at 0.99, that is an acceptable precision.

If necessary, the precision can be increased by setting TolX and possibly other options via optimset:

x = fminbnd(err, 0, 1, optimset('TolX', 1e-8))


Now the result is 0.239922902427111, and the remaining error is 1.49937875448813 · 10-8.

Note that TolX specifies the precision to which $x$ is estimated, not the acceptable size of the remaining error. The default value is 1e-4.

• awesome, thanks man! I had never heard of "fminbnd" but it's perfect :D! – Holymonk May 7 '15 at 19:12
• Right, forgot about that :)! – Holymonk May 7 '15 at 19:24