Picking grain size or efficiently solving nonlinear equation via another way in MATLAB

I have an equation that says essentially, $$J = A_1 * ( \exp( -V * A_2 ) -1 ) + A_3$$ where the output $J$ is what is desired and depends on three constants and the output depends on $V$.

My problem is that I need to efficiently solve the following equation for $\eta$,

$$J = B * ( \exp( C * \eta) - \exp(-D * \eta) ) + A_3$$ where I have $J, B, C, D, A_3$. $J$ is the output from the first formula. $A_3$ is the same parameter as in formula one. My solution is Newton-Raphson, but the time it takes these calculations is very slow when my step size is linearly set. The general procedure of my solution is that it plots formula 1 using known variables, resulting in pairs of points (V,J) of interest. For each J, formula 2 is solved for $\eta$ to create a new series of (V+$\eta$, J) points of interest for further analysis. I've outlined an example script of the procedure.

Can anybody think of a way to set the grain or stp_size in a more efficient way or suggest a much faster computational method? My desired output is also shown below and its general form is very important for later analysis.

function COMPUTATION

upperlimit=1.8531; lowerlimit=-1.8531;

stp_size=0.001;

V=[lowerlimit:stp_size:upperlimit];

for j = 1 : 1 : length(V) J(1,j) = 5.5801*10^(-31) * ( exp(- 1 * V(j) / (1 * 8.6174*10^(-5) * 300) )-1 )*100 - 7.5265; %this is formula (1) if J(1,j) > 0 J(1,j) = 0; end end

for j = 1: length(V) J_BV(j) = (10^(-5) * ( exp( ( 1.7 * 1 * 9.6485*10^4 *V(j) )/(8.3145*300) ) - exp( -(0.1 * 1* 9.6485*10^4 * V(j)/ (8.3145*300) ) ) )); end

GIA = V + 1.2290;

OUTPUT=OP( GIA, -J );

for i = 1 : length(OUTPUT) if isnan(OUTPUT(i)) GIA(i) = NaN; J(i) = NaN;

end end


plot(GIA+OUTPUT, -J, 'p', 'displayname', 'desired output') hold on; plot(GIA, -J, 'r', 'displayname', 'input') legend('toggle') xlim([-0.7 0.3]) end

function OUTPUT=OP(V, J)

OUTPUT = zeros( 1, length(V) );

for j = 2: length(V) B = 10^(-5); C = 1.7 * 1 * 9.6485*10^4/(8.3145*300); D = 0.1 * 1 * 9.6485*10^4/(8.3145*300); x_0 = real( -(8.3145*300 / (C * 1 * 9.6485*10^4)) * log( - J(1,j)/B )); %first guess clear x f_=@(x)B*( exp(C*(x) ) - exp(-D*(x)) ) - J(1,j); %this is formula (2)

if isinf(x_0)
x_0=0;
end

options=optimset('TolX', 1*10^(-1));

if isinf( f_(x_0) )
OUTPUT(1,j) = NaN;
else
[ OUTPUT(1,j), fval, exitvalue ] = fzero( f_, x_0, options);
if exitvalue == -3
OUTPUT(1,j) = NaN;
end

end
end


end

Why not let Matlab do all the work for you? If I understood it correctly, you have a single (because you can combine both equations by eliminating $J$) non-linear equation in either one ($\eta$) or two variables ($\eta$ and $V$). For the two variables case, define your function as

function [res] = F(X)
eta = X[1]
V = X[2]
A1 = 1.0; # these are just dummy values for your constants
A2 = 2.0;
A3 = 3.0;
B = 4.0;
C = 5.0;
D = 6.0;
res = A1*(exp(-V*A2)-1)+A3 - B*(exp(C*eta)-exp(-D*eta))-A3;
end


and then you ask Matlab (or Octave) to solve the equation for you:

fsolve(@F,X0) where X0is an initial guess for $\eta$ and $V$.

• This is certainly faster than my method and gives more stable answers, but I wish it was faster. Maybe this is as fast as it can converge. Thank you! – sciencenewbie Sep 19 '13 at 18:47