How to do Fminsearch- Curve fitting
Show older comments
I am trying to perfrom Fminsearch to fit the image intensity decaying data points to the wave propogation model , to determine constants
I am not sure how to go about the fminsearch. Kindly requesting help.
Below is my code:
% Objective:
%{
1. Import a CT scan image( CT scan of an Cu wire)
2. Extract the intensity from the CT scan image(CT scan of an Cu wire) :
which will be the observed data
3. Define the exponential decay model describing the Wave propagation through a medium
4. Perform fminsearch to determine the constants ( imaginary constants)
in the decay model.
%}
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
%% Importing the CT scan/test image
% fullname = get_full_filename('20220422_5anglestep000.tif')
test_image = imread('test_image.tif');
figure(1)
imshow(test_image)
% Getting the dimensions of the image.
[rows, columns] = size(test_image);
%% % Computung and displaying the histogram.
figure(5)
[pixelCount, grayLevels] = imhist(test_image);
bar(pixelCount);
grid on;
title('Histogram of test image');
xlim([0 grayLevels(end)]); % Scale x axis manually.
%% Extracting the intensities from the medium
% Image represents the wave propgation through a medium in terms of
% intensity vs thickness(displacement) of the medium
% Looking to extract the intensity as a function of displacment from image
% k: displacement ( Z axis locations)
% wave_obs = intensity (Y intenisity)
figure(3)
middleRow = round(size(test_image, 1) / 2) % Find middle row.
wave_obs = test_image(middleRow, :) % Get all columns in the middle row.
% Now plot the intensity.
plot(wave_obs, 'b-', 'LineWidth', 2);
grid on;
xlabel('X Column');
ylabel('Gray Level');
%% Fitting wave_obs data points to the below defined exponential decay model
%% Defining the equation wave = exp(i(1-del)k*z * exp(-beta)*z
%{
i - signifying imaginary part
z - array representing the length of the medium : # of wave_obs data points
k - refractive index
del - constant (to be determined)
beta -constant (to be determined)
wave_obs- data points to fit
%}
k=1.5;
%% fminsearch : HELP NEEDED!
wave_pred = fminsearch(wave_prediction);
predicted_wave = wave_pred(z,k)
function wave_prediction = wave_pred(z,k)
del =5;
beta =7;
k=1.5;
z= 0:0.2:20;
wave1 = exp(-1i*(1-del)*k*z);
wave2 = exp(-beta)*z;
wave_prediction = @(del,beta)wave1.*wave2;
end
3 Comments
Anand Ra
on 29 Apr 2022
Walter Roberson
on 29 Apr 2022
wave_pred = fminsearch(wave_prediction);
At that point in the code, you do not have any function or variable named wave_prediction so it is not obvious what you are trying to do there.
Remember also that fminsearch() needs an initial search point.
predicted_wave = wave_pred(z,k)
I wonder if you should be calling that first and assigning the result to wave_prediction, since the output of the function is a function handle ?
wave_prediction = @(del,beta)wave1.*wave2;
That function handle accepts two parameters, del and beta, and ignores them both and always returns the product of wave1 and wave2. But if you are planning to make that the function handle used by fminsearch() then you have the difficulty that fminsearch() will only pass in a single parameter (that is a vector)
wave1 and wave2 are both defined in terms of the vector z, so the result of executing the function handle would be a vector. But fminsearch() needs a scalar to be returned.
You are trying to do a curve fitting, which requires that you have existing known data points and known corresponding value. It is not immediately clear to me which variables in your code hold the existing values ?
Anand Ra
on 29 Apr 2022
Answers (1)
Currently, you are minimizing your prediction function. You need to be minimizing, not the prediction, but a function that compares your prediction to measured data. You need to provide the measured data as well as an initial gues [del0,beta0] if the unknown parameters
fminsearch(@(p,meas) wave_prediction_Error(p, meas) , [del0,beta0]);
function Error = wave_prediction_Error(params, measurements)
del =params(1);
beta =(2);
k=1.5;
z= 0:0.2:20;
waveprediction = exp(-1i*(1-del)*k*z) .* exp(-beta)*z;
Error = norm( waveprediction - measurements);
end
23 Comments
Matt J
on 29 Apr 2022
And? What was the result?
Anand Ra
on 29 Apr 2022
I made a few modifications to your code below. However, the fundamental problem is that your wave_prediction only has 101 points, but your wave_obs has much more. Therefore, we cannot do the vector subtraction in this line
Error = norm( waveprediction - wave_obs);
load('wave_obs.mat', 'wave_obs')
wave_obs=double(wave_obs);
del0=0.1;
beta0=0.1;
fminsearch(@(p,meas) wave_prediction_Error(p, wave_obs) , [del0,beta0]);
figure(9)
z= 0:0.2:20;
plot(z, wave_obs, 'ro', z, waveprediction, 'b-');
function Error = wave_prediction_Error(params, wave_obs)
del =params(1);
beta =(2);
k=1.5;
z= 0:0.2:20;
wave_prediction = exp(-1i*(1-del)*k*z) .* exp(-beta).*z;
Error = norm( wave_prediction - wave_obs);
end
Matt J
on 29 Apr 2022
It is also suspicious that your wave_obs are purely real-valued, but your wave_prediction is complex-valued. Therefore, it is hard to see how your model could ever agree with wave_obs.
Anand Ra
on 29 Apr 2022
The optimal del and beta will be the output of fminsearch:
params=fminsearch(@(p,meas) wave_prediction_Error(p, wave_obs) , [del0,beta0]);
delOpt=params(1);
betaOpt=params(2)
wave_prediction=@(z)exp(-1i*(1-delOpt)*k*z) .* exp(-betaOpt).*z;
However, there is still the problem that your prediction function produces complex values, so what would it mean to "plot" it? You could certainly plot the absolute values:
z= 0:1:1450;
plot(z,abs(wave_obs),'rx',z,abs( wave_prediction(z)) 'b-')
Anand Ra
on 29 Apr 2022
Matt J
on 29 Apr 2022
For some reason, you moved the plotting commands inside your objective function. That's not where it belongs:
load('wave_obs.txt', 'wave_obs')
wave_obs=double(wave_obs);
del0=1.6419807E-06; % updated
beta0=7.30026262E-10;%updated
% fminsearch(@(p,meas) wave_prediction_Error(p, wave_obs) , [del0,beta0]);
params=fminsearch(@(p,meas) wave_prediction_Error(p, wave_obs) , [del0,beta0]);
delOpt=params(1);
betaOpt=params(2);
final_wave_prediction=@(z)exp(-1i*(1-delOpt)*k*z) .* exp(-betaOpt).*z;
figure(2);
plot(z,abs(wave_obs),'rx',z,abs(final_wave_prediction(z)),'b-')
grid on
grid minor
legend('Observed','Predicted');
xlabel('Displacement (Thickness'); ylabel('Intensity');
title('exponential decay model describing the Wave propagation through a medium');
function Error = wave_prediction_Error(params, wave_obs)
delOpt=params(1);
betaOpt=params(2);
z= 1:1:1451;
k=(2*pi)/0.00000008;
wave_prediction = exp(-1i*(1-del)*k*z) .* exp(-beta).*z;
Error = norm( wave_prediction - wave_obs);
end
Anand Ra
on 29 Apr 2022
Change this back to what we had before (plus a few tweaks that I've inserted),
function Error = wave_prediction_Error(params, wave_obs)
del=params(1);
beta=params(2);
z= 1:numel(wave_obs);
k=(2*pi)/0.00000008;
wave_prediction = exp(-1i*(1-del)*k*z) .* exp(-beta).*z;
Error = norm( wave_prediction(:) - wave_obs(:));
end
Anand Ra
on 29 Apr 2022
Anand Ra
on 29 Apr 2022
Matt J
on 29 Apr 2022
It's complex. Your measurements are real.
Matt J
on 29 Apr 2022
Thirdly, it seems unlikely that in the graph in your photo z is a sequence of integers 1:N like it is in your code
Surely z is supposed to have units as well?
Anand Ra
on 29 Apr 2022
Anand Ra
on 29 Apr 2022
Anand Ra
on 29 Apr 2022
Matt J
on 29 Apr 2022
No, the figure shows that the decaying curves follow equations
and
which are not the model equation curves you have implemented.
Also, the curves decay starting from 1 at z=0. Your wave_obs data are all well above 1. Presumably, there was some sort of data normalization that you were supposed to do.
Also, the data you have attached are not monotonically decaying. They have oscillations:

Anand Ra
on 29 Apr 2022
Categories
Find more on Get Started with Curve Fitting Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!