You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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:

  1. Convert your angle data to radians first with theta_rad = deg2rad(theta_deg).
  2. Open cftool, select theta_rad as X data and I_meas as Y data.
  3. Choose Custom Equation as the model type, then enter:
    a*cos(x - b)^2 + c
  4. Set initial values: a=1.6, b=deg2rad(315), c=0.01
  5. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:55:50