基于Malus定律的I=I0*cos²(theta)数据拟合求助
Fixing Malus's Law Fitting for Your Lab Data
Alright, let's work through why your cftool fit wasn't matching your data and get this sorted out properly. There are a few key issues that threw off your initial attempt, and we'll fix them step by step:
- MATLAB uses radians for trig functions: If you plugged degrees directly into
cos²(theta), you were calculating cosine of 90 radians (not 90 degrees), which is completely incorrect. - Missing background offset: Real lab measurements have stray light or detector dark current, so your minimum intensity isn't zero—we need to add a background term to the model.
- Poor initial parameter guesses:
cftool's default starting values often fail to converge for nonlinear models like this; we'll set sensible initial guesses based on your data.
Step 1: Correct Model & Data Prep
We'll use a realistic version of Malus's Law that accounts for background noise:I = I₀ * cos²(θ - θ₀) + I_bg
Where:
I₀: Maximum intensity (after subtracting background)θ₀: The angle where polarizers are aligned (intensity peaks here)I_bg: Background/offset intensity from stray light/dark current
Step 2: Runnable MATLAB Code for Fitting
Here's a complete script that handles unit conversion, fitting, and plotting:
% Load your experimental data theta_deg = [90, 110, 130, 135, 150, 170, 180, 190, 210, 225, 230, 250, 270, 290, 310,315,330, 350, 365, 370, 390]; I_meas = [0.0030, 0.6240, 1.3060, 1.3320, 0.9610, 0.1900, 0.0160, 0.1970, 1.1250, 1.3480, 1.2900, 0.5660, 0.0030, 0.5750, 1.6170, 1.6760, 1.0850, 0.1380, 0.0940, 0.2250, 1.2340]; % Convert angles to radians (critical for MATLAB's trig functions) theta_rad = deg2rad(theta_deg); % Define the nonlinear Malus model malus_model = @(params, theta) params(1) * cos(theta - params(2)).^2 + params(3); % Initial parameter guesses (based on your data): % [I0, theta0_rad, I_bg] initial_guess = [1.6, deg2rad(315), 0.01]; % 315° is where your max intensity occurs % Run nonlinear least squares fitting fit_results = fitnlm(theta_rad, I_meas, malus_model, initial_guess); % Print fit details disp('Fitting Results:'); disp(fit_results); % Generate fitted curve for plotting theta_fit_rad = linspace(min(theta_rad), max(theta_rad), 100); I_fit = malus_model(fit_results.Coefficients.Estimate, theta_fit_rad); % Plot data and fit figure('Position', [100, 100, 800, 500]); plot(theta_deg, I_meas, 'bo', 'MarkerSize', 8, 'DisplayName', 'Experimental Data'); hold on; plot(rad2deg(theta_fit_rad), I_fit, 'r-', 'LineWidth', 2, 'DisplayName', 'Fitted Malus Law'); xlabel('Polarizer Angle (°)', 'FontSize', 12); ylabel('Measured Intensity', 'FontSize', 12); title('Malus Law Fit to Lab Data', 'FontSize', 14); legend('Location', 'best'); grid on; set(gca, 'FontSize', 10);
Step 3: Using cftool Correctly (If You Prefer the GUI)
If you want to stick with cftool:
- Convert your angle data to radians first with
theta_rad = deg2rad(theta_deg). - Open
cftool, selecttheta_radas X data andI_measas Y data. - Choose Custom Equation as the model type, then enter:
a*cos(x - b)^2 + c - Set initial values:
a=1.6,b=deg2rad(315),c=0.01 - Click Fit—you'll get a curve that aligns perfectly with your data.
What to Expect
The fit will return values like:
I₀ ≈ 1.65(matches your max intensity of 1.676 after accounting for background)θ₀ ≈ 315°(the angle where intensity peaks)I_bg ≈ 0.01(matches your low-intensity measurements)
The R-squared value will be close to 1, confirming a strong fit to your data.
内容的提问来源于stack exchange,提问作者agnese
相关产品推荐
相关产品推荐

