MATLAB的lsqnonlin求解器远离解决方案

时间:2015-10-29 12:38:46

标签: matlab optimization mathematical-optimization solver

我有一个合适的问题,我正在尝试使用MATLAB的lsqnonlin函数解决它并且它的工作非常糟糕。特别是,如果我给它实际解决方案作为起点,求解器继续从那里移开(尽管拟合函数返回该输入的所有零的向量)并产生可怕的东西。我的代码在下面,但它有点长,所以我为此道歉,但我不确定这种特殊情况究竟是什么造成了这种行为,就像在其他情况下那样。

fitting_demo.m:

% Parameters for image
imagemat = zeros(32, 32);
x_centre = 5; y_centre = -10; radius = 3; psf_sigma = 1; height = 1;

% Generate image to fit
actual_image = image_sphere_thin(x_centre, y_centre, radius, psf_sigma, height, imagemat);

figure

% Plot actual image
subplot(2, 1, 1)
imagesc(actual_image)
axis equal
title('Actual image')

% Set up fitting function
x0 = [x_centre, y_centre, radius, psf_sigma, height]; % The solver starts from the solution!
f = @(x)fit_image_sphere_thin(x, imagemat);

% Fit
options = optimoptions(@lsqnonlin, 'Display', 'iter');
[fit, resnorm, residual, exitflag, output] = lsqnonlin(f, x0, [], [], options);

% Display image generated using fitted parameters
subplot(2, 1, 2)
imagesc(image_sphere_thin(fit(1), fit(2), fit(3), fit(4), fit(5), imagemat))
axis equal
title('Fitted image')

fit_image_sphere_thin.m:

function deltas = fit_image_sphere_thin(x0, actual_image)

x_centre       = x0(1);
y_centre       = x0(2);
radius         = x0(3);
% psf_sigma      = x0(4); % Commented out to stop crazy things
psf_sigma = 1;
% height         = x0(5); % Commented out to stop crazy things
height = 1;

imagemat = zeros(size(actual_image));

sim_image = image_sphere_thin(x_centre, y_centre, radius, psf_sigma, height, imagemat);

sim_vector = sim_image(:);
actual_vector = actual_image(:);

deltas = actual_vector - sim_vector;

end

image_sphere_thin.m:

function I = image_sphere_thin(x_centre, y_centre, radius, psf_sigma, height, imagemat)

image_width = size(imagemat, 2);
image_height = size(imagemat, 1);

image_centre_x = image_width / 2;
image_centre_y = image_height / 2;

x = (1:image_width) - image_centre_x;
y = -(1:image_height) + image_centre_y;

[x, y] = meshgrid(x, y);
X = [x(:) y(:)];

image_vector = cross_section_sphere_thin(x_centre, y_centre, radius, psf_sigma, height, X);

imagemat = reshape(image_vector, size(imagemat));
I = imagemat;

end

cross_section_sphere_thin.m:

function I = cross_section_sphere_thin(x_centre, y_centre, radius, psf_sigma, height, X)

r = sqrt((X(:, 1) - x_centre).^2 + (X(:, 2) - y_centre).^2);
psf_variance = psf_sigma^2;
I = height * (exp(-(r - radius).^2 / (2 * psf_sigma)) - exp(-(r + radius).^2 / (2 * psf_sigma))) ./ r;
I(r == 0) = (2 * radius * height / psf_variance) * exp(-(radius^2) / (2 * psf_variance));

end

0 个答案:

没有答案