How to use fzero and arrayfun to find roots?

1 view (last 30 days)
Hi!I got a problem when I ran my code.
This is my code:
f = [1*1e9 2*1e9 3*1e9];
w=2*pi*f;
z0 = 376.73415;
c = 2.997925e8;
L1 = 10*1e-3;
L2 = 20*1e-3;
dL = 0.01*1e-3;
miu0 = z0/c;
miur = 1;
y0 = 1i.*w/c;
ys = @(w,episr) 1i*w./c.*sqrt( miur*episr );
the = @(episr) episr./sqrt(miur);
Zin3_1 = @(w,episr) tanh(ys(w,episr)*L2);
Zin3_2 = @(w,episr) the(episr).*tanh(y0*dL);
Zin3_3 = @(w,episr) the(episr).*( 1+the(episr).*tanh(y0*dL).*tanh(ys(w,episr)*L2) );
Zin3 =@(w,episr) ZL1.*( Zin3_1(w,episr) + Zin3_2(episr) + Zin3_3(w,episr).*tanh(y0*L1) )...
./( Zin3_3(w,episr) +( Zin3_1(w,episr) + Zin3_2(w,episr) ).*tanh(y0*L1) );
S11 = @(w,episr) ( Zin3(w,episr)-Z0 )./( Zin3(w,episr)+Z0 );
reS11=@(w,episr) real( S11(w,episr) );
arrayfun( @(i) fzero( @(episr) reS11( w(i),episr ),3 ),1:numel(w) )
After I ran my code, I got a message:Operands to the and && operators must be convertible to logical scalar values.
So I ran my code step by step, I found a problem in Zin3_3.
But I don't know how to fix it.
Does anyone help me? Thanks!

Accepted Answer

Walter Roberson
Walter Roberson on 9 Nov 2015
In Zin3 you call Zin3_2(episr) but that routine needs two input arguments.
  6 Comments
Walter Roberson
Walter Roberson on 9 Nov 2015
The general technique of using arrayfun is fine, but your expression to be solved turns out to be a vector rather than a scalar.
I recommend that you rewrite your expressions so that you distinguish by variable name between the w that you assign in your second line, and the w that is being passed in to the routines, the value that you are trying to solve for. For example call one of them W instead of w. I think when you do that and follow through the logic that you will find that the w that is in y0 should not be the w that you compute originally and should instead by the trial w. Like this:
ZL1 = rand(); %you never defined it
f = [1*1e9 2*1e9 3*1e9];
w=2*pi*f;
z0 = 376.73415;
c = 2.997925e8;
L1 = 10*1e-3;
L2 = 20*1e-3;
dL = 0.01*1e-3;
miu0 = z0/c;
miur = 1;
y0 = @(W) 1i.*W/c;
ys = @(W,episr) 1i*W./c.*sqrt( miur*episr );
the = @(episr) episr./sqrt(miur);
Zin3_1 = @(W,episr) tanh(ys(W,episr)*L2);
Zin3_2 = @(W,episr) the(episr).*tanh(y0(W)*dL);
Zin3_3 = @(W,episr) the(episr).*( 1 + the(episr) .* tanh(y0(W)*dL) .* tanh(ys(W,episr)*L2) );
Zin3 =@(W,episr) ZL1.*( Zin3_1(W,episr) + Zin3_2(W,episr) + Zin3_3(W,episr).*tanh(y0(W)*L1) ) ./ ( Zin3_3(W,episr) + ( Zin3_1(W,episr) + Zin3_2(W,episr) ).*tanh(y0(W)*L1) );
S11 = @(W,episr) ( Zin3(W,episr)-z0 ) ./ ( Zin3(W,episr) + z0 );
reS11 = @(W,episr) real( S11(W,episr) );
arrayfun( @(i) fzero( @(episr) reS11( w(i),episr ),3 ),1:numel(w) )
With those initial w values, two of the three will give results as NaN. I have investigated and found that the range that would need to be searched over for a change in sign can be quite narrow, depending on the initial ZL1 value.
San-Chi Yan
San-Chi Yan on 9 Nov 2015
Edited: San-Chi Yan on 10 Nov 2015
Sorry! I missed a error again... I forgot it from posting mt code.
Thank you for your respond! I will remember that.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!