nonlinear regression for multiple variable parameter
9 views (last 30 days)
Show older comments
andrea rigotto
on 27 Sep 2023
Commented: Star Strider
on 28 Sep 2023
I'm trying to write code to perform a nonlinear regression with multiple variables, but i have no idea how to do it.
i need to use Keq and pressure like Xdata and define the x1,x2,x3 from the regression.
I hope I have explained myself.
Function value and YDATA sizes are not equal.
Error in prova3 (line 49)
x_fit = lsqcurvefit(T, x0, [pressure Keq], temperature);
clc
clear all
close all
%%
%read all .xlsx file inside the folder
path = dir('C:\Users\Andrea\Desktop\matlab\input_file\*.xlsx');
%cicle for obtain the sample data (P-T-Ni) content directly from the .xlsx file
for i=1:1
table = readtable(strcat('C:\Users\Andrea\Desktop\matlab\input_file\',path(i).name));
temperature(:,i) = table.temperature;
pressure(:,i) = table.pressure;
Ni_grt(:,i) = table.Ni_Grt;
Ni_ol(:,i) = table.Ni_Ol;
Cr_grt(:,i) = table.Wt_Cr;
Ca_grt(:,i) = table.Wt_Ca;
end
%% calculation
%Keq
Ni_grt = Ni_grt(~isnan(Ni_grt), :);
Keq= log(Ni_grt/2900);
%temperature from C to K
temperature = temperature + 273.15;
%olivine mean
Ni_ol = Ni_ol(~isnan(Ni_ol), :);
mean_Ni_ol = mean(Ni_ol);
%% ignore the NaN value
temperature = temperature(~isnan(temperature), :);
pressure = pressure(~isnan(pressure), :);
Ca_grt = Ca_grt(~isnan(Ca_grt), :);
Cr_grt = Cr_grt(~isnan(Cr_grt), :);
%% Calculate the parameters (ΔH, ΔV, ΔS)
% function of T
T = @(x,pressure,Keq) (x(1) + pressure * x(2)) ./ (x(3) - log(Keq));
% random start parameters (ΔH, ΔV, ΔS)
x0 = [1, 1, 1];
% nonlinear regression with lsqcurvefit
x_fit = lsqcurvefit(T, x0, [pressure Keq], temperature);
% Extract the fitted parameters
DeltaH = x_fit(1);
DeltaV = x_fit(2);
DeltaS = x_fit(3);
% the new value od temperature from Ni_grt of database
predicted_temperature = T(x_fit, pressure);
% print the result
fprintf('Parametri adattati:\n');
fprintf('ΔH = %.2f\n', DeltaH);
fprintf('ΔV = %.2f\n', DeltaV);
fprintf('ΔS = %.2f\n', DeltaS);
fprintf('Ni_ol = %.2f\n', mean_Ni_ol);
%% diff TNi-T
deltaT = predicted_temperature-temperature;
mean_deltaT = mean(deltaT);
fprintf('mean_detaT = %.2f\n', mean_deltaT);
0 Comments
Accepted Answer
Star Strider
on 27 Sep 2023
Your code works. The only change required was to create the ‘pressure_Keq’ matrix as the independent variable and then change ‘T’ to refer to it correctly internally.
Try this —
clc
clear all
close all
%%
%read all .xlsx file inside the folder
% path = dir('C:\Users\Andrea\Desktop\matlab\input_file\*.xlsx');
path = dir('*.xlsx');
%cicle for obtain the sample data (P-T-Ni) content directly from the .xlsx file
for i=1:1
% table = readtable(strcat('C:\Users\Andrea\Desktop\matlab\input_file\',path(i).name));
table = readtable(path(i).name)
temperature(:,i) = table.temperature;
pressure(:,i) = table.pressure;
Ni_grt(:,i) = table.Ni_Grt;
Ni_ol(:,i) = table.Ni_Ol;
Cr_grt(:,i) = table.Wt_Cr;
Ca_grt(:,i) = table.Wt_Ca;
end
%% calculation
%Keq
Ni_grt = Ni_grt(~isnan(Ni_grt), :);
Keq= log(Ni_grt/2900);
%temperature from C to K
temperature = temperature + 273.15;
%olivine mean
Ni_ol = Ni_ol(~isnan(Ni_ol), :);
mean_Ni_ol = mean(Ni_ol);
%% ignore the NaN value
temperature = temperature(~isnan(temperature), :);
pressure = pressure(~isnan(pressure), :);
Ca_grt = Ca_grt(~isnan(Ca_grt), :);
Cr_grt = Cr_grt(~isnan(Cr_grt), :);
%% Calculate the parameters (ΔH, ΔV, ΔS)
% function of T
pressure_Keq = [pressure Keq]; % Create The Independent Variable As A Matrix, Then Address Its Columns Appropriately In The Objective Function
T = @(x,pressure_Keq) (x(1) + pressure_Keq(:,1) * x(2)) ./ (x(3) - log(pressure_Keq(:,2)));
% random start parameters (ΔH, ΔV, ΔS)
x0 = [1, 1, 1];
% nonlinear regression with lsqcurvefit
x_fit = lsqcurvefit(T, x0, pressure_Keq, temperature);
% Extract the fitted parameters
DeltaH = x_fit(1);
DeltaV = x_fit(2);
DeltaS = x_fit(3);
% the new value od temperature from Ni_grt of database
predicted_temperature = T(x_fit, pressure_Keq);
% print the result
fprintf('Parametri adattati:\n');
fprintf('ΔH = %.2f\n', DeltaH);
fprintf('ΔV = %.2f\n', DeltaV);
fprintf('ΔS = %.2f\n', DeltaS);
fprintf('Ni_ol = %.2f\n', mean_Ni_ol);
%% diff TNi-T
deltaT = predicted_temperature-temperature;
mean_deltaT = mean(deltaT);
fprintf('mean_detaT = %.2f\n', mean_deltaT);
.
2 Comments
Star Strider
on 28 Sep 2023
That may be because you are calculating the logarithm of a negative number.
I just noticed this now, that these two calculations appear to be redundant:
Keq = log(Ni_grt/2900);
that division is likely to result in values less than 1 (so the log of ‘Keq’ will be negative in those instances), and later you take the log of ‘Keq’ in ‘T’:
T = @(x,pressure_Keq) (x(1) + pressure_Keq(:,1) * x(2)) ./ (x(3) - log(pressure_Keq(:,2)));
Perhaps taking the log of ‘Keq’ in ‘T’ needs to be changed, so that you are only subtracting ‘Keq’ and not the log of it.
I do not know what you are calculating, so I am hesitant to make any other changes to your code.
.
More Answers (0)
See Also
Categories
Find more on Linear Regression 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!