Programmatically find fzero of two RCL functions
2 次查看(过去 30 天)
显示 更早的评论
How do I fix my code to programmatically find the fzero of two functions? I had to hand-code the functions funcVL and funcVR from model fit coefficients. I want to do that programmatically, then find fzero (intersection point) of the two function curves. Need some help here. Thank you
% find intersection (frequency) of two RCL functions
load RCL_vars.mat % creates 3 vectors, f, VL, VR from data
% function calls
createFitVL(f, VL)
createFitVR(f, VR)
% find intersection point, f
x = f;
funcVL = @ (x) -3.948*exp(-0.658*x)+3.898;
funcVR = @ (x) 3.856*exp(0.2436*x)+0.2436;
%use fzero with the function: @(x) funcVL(x) - funcVR(x).
soltn = fzero(@(x) funcVR(x)- funcVL(x), [0, 10])
%%
function [fitresult, gof] = createFitVL(f, VL)
%CREATEFIT(F,VL)
% Create a fit.
%
% Data for 'untitled fit 1' fit:
% X Input: f
% Y Output: VL
% Output:
% fitresult : a fit object representing the fit.
% gof : structure with goodness-of fit info.
%
% See also FIT, CFIT, SFIT.
% Auto-generated by MATLAB on 26-Feb-2025 15:57:28
%% Fit: 'untitled fit 1'.
[xData, yData] = prepareCurveData( f, VL );
% Set up fittype and options.
ft = fittype( 'a*exp(-b*x)+c', 'independent', 'x', 'dependent', 'y' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [0.317099480060861 0.950222048838355 0.0344460805029088];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
% Plot fit with data.
figure( 'Name', 'untitled fit 1' );
h = plot( fitresult, xData, yData );
legend( h, 'VL vs. f', 'untitled fit 1', 'Location', 'NorthEast', 'Interpreter', 'none' );
% Label axes
xlabel( 'f', 'Interpreter', 'none' );
ylabel( 'VL', 'Interpreter', 'none' );
grid on
end
%
hold on
%% Fit: 'untitled fit 1'.
function [fitresult, gof] = createFitVR(f, VR)
[xData, yData] = prepareCurveData( f, VR );
% Set up fittype and options.
ft = fittype( 'a*exp(-b*x)+c', 'independent', 'x', 'dependent', 'y' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [0.257508254123736 0.840717255983663 0.254282178971531];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
% Plot fit with data.
figure( 'Name', 'untitled fit 1' );
h = plot( fitresult, xData, yData );
legend( h, 'VR vs. f', 'untitled fit 1', 'Location', 'NorthEast', 'Interpreter', 'none' );
% Label axes
xlabel( 'f', 'Interpreter', 'none' );
ylabel( 'VR', 'Interpreter', 'none' );
grid on
end
0 个评论
采纳的回答
Star Strider
2025-2-27
It seems that the curves don’t intersect.
The ‘funcVR’ function never crosses zero, although the ‘funcVL’ function does —
funcVL = @ (x) -3.948*exp(-0.658*x)+3.898;
funcVR = @ (x) 3.856*exp(0.2436*x)+0.2436;
xs = fzero(@(x) funcVL(x)-funcVR(x), randn)
xv = linspace(-1E+2, 1E+2, 1E3);
yL = funcVL(xv);
yR = funcVR(xv);
ixx = find(diff(sign(yL-yR)))
Zpts = [fzero(funcVR, 0.5) fzero(funcVL, 0.5)]
figure
plot(xv, yR, DisplayName='funcVR')
hold on
plot(xv, yL, DisplayName='funcVL')
plot(Zpts(2), 0, 'mp', DisplayName=sprintf('funcVL(%.4f) = 0',Zpts(2)))
hold off
grid
legend(Location='best')
xlim([-100 100])
ylim([-5 5])
.
5 个评论
Steven Lord
2025-2-27
Yes, and from the presence of this line in your createFitVL local function it seems you've already used it.
% Auto-generated by MATLAB on 26-Feb-2025 15:57:28
Or if you don't want to generate code, rather than manually creating the anonymous function yourself you can use the fitresult output argument (created by the fit function) from the local functions directly in the anonymous function you pass to the zero finder. Let's make two fits to the census data included in MATLAB:
load census
fitobj1 = fit(cdate, pop, 'poly1')
fitobj2 = fit(cdate, pop, 'poly2')
We can see from a plot of the two fits that they do cross.
plot(fitobj1)
hold on
plot(fitobj2)
Let's computing one of the crossing points using a starting guess of 1900. Here I'm directly evaluating the two fits inside crossingFcn.
crossingFcn = @(x) fitobj1(x)-fitobj2(x);
format longg
crossingValue = fzero(crossingFcn, 1900)
Let's show the crossing point fzero found for this starting point. I made the circle a bit bigger and gave it a descriptive name for the legend.
figure
plot(fitobj1);
hold on
plot(fitobj2);
plot(crossingValue, fitobj1(crossingValue), 'ko', ...
MarkerSize = 10, DisplayName = "Crossing point")
A different starting point could give the other crossing.
crossingValue = fzero(crossingFcn, 1800)
Star Strider
2025-2-27
If I understand correcttly what you want to do, it is relatively straightforward to get the function intersections.
This gives the single intersection at (1.8292,2.7132) —
funcVL = @ (x) -3.948*exp(-0.658*x)+3.898;
funcVR = @ (x) 3.856*exp(-0.2436*x)+0.2436;
xv = linspace(-2E+1, 1.5E+1, 1E3);
yL = funcVL(xv);
yR = funcVR(xv);
ixx = find(diff(sign(yL-yR)));
idxrng = max(1,ixx-1) : min(numel(xv),ixx+1);
xisx = interp1(yR(idxrng)-yL(idxrng), xv(idxrng), 0)
yisx = interp1(xv(idxrng), yR(idxrng), xisx)
ydif = yR - yL;
funcD = @(x) funcVR(x)-funcVL(x);
[xmin,fv] = fminsearch(@(x)norm(funcD(x)), randn)
[xmin,fv] = fzero(@(x)funcD(x), randn)
figure
plot(xv, yR, DisplayName='funcVR')
hold on
plot(xv, yL, DisplayName='funcVL')
% plot(xv, ydif, DisplayName='funcVR-funcVL', LineWidth=3)
plot(xisx, yisx, 'rs', DisplayName='Intersection')
hold off
grid
legend(Location='best')
xlim([-5 10])
ylim([-1 5])
text(xisx,yisx,sprintf(' \\leftarrow (%.6f, %.6f)',xisx,yisx), Horiz='left', Vert='middle')
This appears to provide a reasonable answer for the intersection.
.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Get Started with Curve Fitting Toolbox 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!