Programmatically find fzero of two RCL functions
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Doug Leaffer
le 27 Fév 2025
Commenté : Star Strider
le 27 Fév 2025
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 commentaires
Réponse acceptée
Star Strider
le 27 Fév 2025
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 commentaires
Steven Lord
le 27 Fév 2025
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
le 27 Fév 2025
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.
.
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Get Started with Curve Fitting Toolbox dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!