How to use fzero and arrayfun to find roots?
2 views (last 30 days)
Show older comments
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!
0 Comments
Accepted Answer
Walter Roberson
on 9 Nov 2015
In Zin3 you call Zin3_2(episr) but that routine needs two input arguments.
6 Comments
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.
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!