I am coding a equation for curve fitting, but I am facing inaccuracy. I am not getting Elastic plateau in the curve. Can anyone guide me how I can address the issue.

clc; close all;
%% ---- Load data --
file = 'data.xlsx';
T = readtable(file); % expects columns: Strain, Stress (in GPa)
Warning: Column headers from the file were modified to make them valid MATLAB identifiers before creating variable names for the table. The original column headers are saved in the VariableDescriptions property.
Set 'VariableNamingRule' to 'preserve' to use the original column headers as table variable names.
disp(T.Properties.VariableNames)
{'Strain_mm_mm_'} {'Stress_GPa_'}
epsl = T.Strain_mm_mm_(:); % ensure column vector
sig = T.Stress_GPa_(:) * 1000; % convert GPa -> MPa
% keep only finite rows
good = isfinite(epsl) & isfinite(sig);
epsl = epsl(good);
sig = sig(good);
% (optional) trim extreme epsilon to avoid 1/(1-eps) blow-up in model
epsl = min(epsl, 0.981);
%% ---- Known strain rates -------------------------------------------------
edot = 0.000617; % test strain rate [s^-1]
edot0 = edot; % reference strain rate [s^-1]
%% ---- Initial guesses & bounds ------------------------------------------
% [A, E, B, m, n, a, b]
p0 = [0.4, 2000, 0.3, 0.95, 2.0, -0.05, 0.150]; % initial params (MPa-based)
lb = [-0.1, 1.2, -.01, -1, 1, 1, 0.01 ];
ub = [2, 20, 1, 5, 5, 4.0, 0.5 ];
%% ---- Fit with lsqcurvefit (Optimization Toolbox) -----------------------
model = @(p,eps) constitutive_model(eps, edot, p(1), p(2), p(3), p(4), p(5), p(6), p(7), edot0);
try
opts = optimoptions('lsqcurvefit','Display','iter','MaxIterations',1000);
[pfit, ~] = lsqcurvefit(model, p0, epsl, sig, lb, ub, opts);
catch ME
warning('lsqcurvefit unavailable (%s). Falling back to fminsearch (unconstrained).', ME.identifier);
obj = @(p) sum((model(p,epsl) - sig).^2);
pfit = fminsearch(obj, p0);
end
Norm of First-order Iteration Func-count Resnorm step optimality 0 8 1.35286e+07 5.23e+07 1 16 2.49293e+06 0.746691 7.98e+06 2 24 474328 0.819711 1.22e+06 3 32 93370.3 0.652941 1.88e+05 Objective function returned complex; trying a new point... 4 40 93370.3 0.223895 1.88e+05 5 48 85651.1 0.0111948 1.71e+05 6 56 71978.8 0.0223895 1.4e+05 7 64 50519.9 0.044779 9.4e+04 8 72 24094.8 0.089558 4.08e+04 Objective function returned complex; trying a new point... 9 80 24094.8 0.179116 4.08e+04 10 88 22378.6 0.0089558 3.76e+04 11 96 19264.9 0.0179116 3.18e+04 12 104 14147.2 0.0358232 2.26e+04 13 112 7295.89 0.0716464 1.09e+04 Objective function returned Inf; trying a new point... 14 120 7295.89 0.143293 1.09e+04 15 128 6820.58 0.00716464 1.01e+04 16 136 5944.95 0.0143293 8.7e+03 17 144 4463.38 0.0286586 6.38e+03 18 152 2375.57 0.0573171 3.24e+03 Objective function returned Inf; trying a new point... 19 160 2375.57 0.114634 3.24e+03 20 168 2225.43 0.00573171 3.03e+03 21 176 1946.42 0.0114634 2.63e+03 22 184 1466.67 0.0229269 1.95e+03 23 192 772.508 0.0458537 1.06e+03 Objective function returned Inf; trying a new point... 24 200 772.508 0.0917074 1.06e+03 25 208 721.962 0.00458537 1e+03 26 216 627.748 0.00917074 887 27 224 465.008 0.0183415 686 Objective function returned Inf; trying a new point... 28 232 465.008 0.036683 686 29 240 450.879 0.00183415 668 Objective function returned Inf; trying a new point... 30 248 450.879 0.0036683 668 31 256 449.485 0.000183415 667 32 264 446.708 0.00036683 663 33 272 441.187 0.000733659 656 34 280 430.281 0.00146732 642 Objective function returned Inf; trying a new point... 35 288 430.281 0.00293464 642 36 296 429.202 0.000146732 641 37 304 427.051 0.000293464 638 Objective function returned Inf; trying a new point... 38 312 427.051 0.000586927 638 39 320 426.837 2.93464e-05 638 40 328 426.408 5.86927e-05 637 41 336 425.551 0.000117385 636 Objective function returned Inf; trying a new point... 42 344 425.551 0.000234771 636 43 352 425.465 1.17385e-05 636 Objective function returned Inf; trying a new point... 44 360 425.465 2.34771e-05 636 Objective function returned Inf; trying a new point... 45 368 425.465 1.17385e-06 636 46 376 425.465 5.86927e-08 636 Local minimum possible. lsqcurvefit stopped because the size of the current step is less than the value of the step size tolerance.
sigma_fit = model(pfit, epsl);
%% ---- Goodness of fit (R^2, adj. R^2, RMSE) -----------------------------
SSE = sum((sig - sigma_fit).^2);
SST = sum((sig - mean(sig)).^2);
R2 = 1 - SSE/SST;
n = numel(sig);
k = numel(pfit); % number of fitted parameters
adjR2 = 1 - (1 - R2) * (n - 1) / max(n - k - 1, 1);
RMSE = sqrt(SSE / n);
% Print to console
fprintf('\nGoodness of fit:\n');
Goodness of fit:
fprintf('R^2 = %.6f\n', R2)
R^2 = -967.068970
fprintf('Adj R^2 = %.6f\n', adjR2);
Adj R^2 = -976.467698
fprintf('RMSE = %.6f MPa\n', RMSE)
RMSE = 0.763955 MPa
%% ---- Plot and Save ------------------------------------------------------
fig = figure; hold on;
plot(epsl, sig, 'k-', 'MarkerFaceColor','k','MarkerSize',2, 'DisplayName','Experimental');
plot(epsl, sigma_fit,'r-', 'LineWidth',1, 'DisplayName','Fitted model');
xlabel('Strain \epsilon');
ylabel('Stress \sigma_d (MPa)');
title(['Fitted Constitutive Model at \epsilon-dot = ', num2str(edot), ' s^{-1}']);
legend show; grid on;
% Add a readable stats box
ax = gca;
xL = xlim(ax); yL = ylim(ax);
txt = {sprintf('R^2 = %.4f', R2), ...
sprintf('Adj R^2 = %.4f', adjR2), ...
sprintf('RMSE = %.3g MPa', RMSE)};
text(xL(1) + 0.02*range(xL), yL(2) - 0.04*range(yL), txt, ...
'VerticalAlignment','top', 'BackgroundColor','w', ...
'Margin',6, 'EdgeColor',[0.1 0.1 0.1], 'FontWeight','bold');
% Save the figure
saveas(fig, 'fitted_model_plot.png'); % PNG
% For crisper output you can also use:
% exportgraphics(fig,'fitted_model_plot.png','Resolution',300);
%% ---- Print parameters ---------------------------------------------------
fprintf('\nFitted Parameters:\n');
Fitted Parameters:
fprintf('A = %.4f MPa\n', pfit(1));
A = 0.0000 MPa
fprintf('E = %.4f MPa\n', pfit(2));
E = 5.8811 MPa
fprintf('B = %.4f MPa\n', pfit(3));
B = 0.0227 MPa
fprintf('m = %.4f\n', pfit(4));
m = 2.9336
fprintf('n = %.4f\n', pfit(5));
n = 1.3294
fprintf('a = %.4f\n', pfit(6));
a = 2.5000
fprintf('b = %.4f\n', pfit(7));
b = 0.1500
%% ===================== Local functions (MUST be at file end) =====================
function sigma_d = constitutive_model(epsilon, edot, A, E, B, m, n, a, b, edot0)
% Vector-safe guards
epsilon = min(max(epsilon, 0.001), 0.99); % keep in [0,1)
one_me = max(1 - epsilon, eps);
% Static part
term1 = A .* (1 - exp(-(E./A) .* epsilon .* (1 - epsilon))).^m;
term2 = B .* (epsilon ./ one_me).^n;
sigma_static = term1 + term2;
% Strain-rate factor
rate_factor = 1 + (a + b .* epsilon) .* log(edot ./ edot0);
sigma_d = sigma_static .* rate_factor;
end

Answers (1)

You need a better initial guess. Also, you should exclude the data from the linear elastic region, since clearly that is not captured by your model equation.
file = 'data.xlsx';
[epsl,sig]=readvars(file) ;
sig=sig*1000;% convert GPa -> MPa
% keep only finite and mid-range data
good = isfinite(epsl) & isfinite(sig) & epsl>0.15 & epsl<0.981;
epsl = epsl(good);
sig = sig(good);
%% ---- Known strain rates -------------------------------------------------
edot = 0.000617; % test strain rate [s^-1]
edot0 = edot; % reference strain rate [s^-1]
%% ---- Initial guesses & bounds ------------------------------------------
% [A, E, B, m, n, a, b]
p0 = [0.04, 100, 0.03, 0.95, 2.0, -0.05, 0.150]; % initial params (MPa-based)
lb = [-0.1, 1.2, -.01, -1, 1, 1, 0.01 ];
ub = [2, 20, 1, 5, 5, 4.0, 0.5 ];
%% ---- Fit with lsqcurvefit (Optimization Toolbox) -----------------------
model = @(p,eps) constitutive_model(eps, edot, p(1), p(2), p(3), p(4), p(5), p(6), p(7), edot0);
try
opts = optimoptions('lsqcurvefit','Display','iter','MaxIterations',1000);
[pfit, ~] = lsqcurvefit(model, p0, epsl, sig, lb, ub, opts);
catch ME
warning('lsqcurvefit unavailable (%s). Falling back to fminsearch (unconstrained).', ME.identifier);
obj = @(p) sum((model(p,epsl) - sig).^2);
pfit = fminsearch(obj, p0);
end
Norm of First-order Iteration Func-count Resnorm step optimality 0 8 32818.8 1.19e+05 1 16 5880.21 0.190567 1.77e+04 Objective function returned complex; trying a new point... 2 24 5880.21 0.183082 1.77e+04 3 32 5003.93 0.00915412 1.5e+04 4 40 3537.19 0.0183082 1.06e+04 5 48 1554.94 0.0366165 4.58e+03 6 56 273.676 0.0732329 766 Objective function returned complex; trying a new point... 7 64 273.676 0.140406 766 8 72 202.263 0.00702032 568 9 80 95.1124 0.0140406 344 10 88 6.97485 0.0280813 70.4 11 96 0.332829 0.0561625 10.9 12 104 0.0509524 0.0466304 1.25 13 112 0.040492 0.112325 11.3 14 120 0.0340305 0.22465 48 15 128 0.0340305 0.200009 48 16 136 0.0254048 0.0500021 21.5 17 144 0.0212187 0.100004 24.5 18 152 0.014874 0.0570038 15.4 19 160 0.00842121 0.000418076 0.0642 20 168 0.00775609 0.00339075 0.000648 21 176 0.00775564 0.00319446 4.24e-05 Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
sigma_fit = model(pfit, epsl);
postAnalysis(epsl,sig,pfit,sigma_fit,edot)
Goodness of fit: R^2 = 0.962642 Adj R^2 = 0.962249 RMSE = 0.003395 MPa
%% ===================== Local functions (MUST be at file end) =====================
function sigma_d = constitutive_model(epsilon, edot, A, E, B, m, n, a, b, edot0)
% Vector-safe guards
epsilon = min(max(epsilon, 0.001), 0.99); % keep in [0,1)
one_me = max(1 - epsilon, eps);
% Static part
term1 = A .* (1 - exp(-(E./A) .* epsilon .* (1 - epsilon))).^m;
term2 = B .* (epsilon ./ one_me).^n;
sigma_static = term1 + term2;
% Strain-rate factor
rate_factor = 1 + (a + b .* epsilon) .* log(edot ./ edot0);
sigma_d = sigma_static .* rate_factor;
end
function postAnalysis(epsl,sig,pfit, sigma_fit,edot)
%% ---- Goodness of fit (R^2, adj. R^2, RMSE) -----------------------------
SSE = sum((sig - sigma_fit).^2);
SST = sum((sig - mean(sig)).^2);
R2 = 1 - SSE/SST;
n = numel(sig);
k = numel(pfit); % number of fitted parameters
adjR2 = 1 - (1 - R2) * (n - 1) / max(n - k - 1, 1);
RMSE = sqrt(SSE / n);
% Print to console
fprintf('\nGoodness of fit:\n');
fprintf('R^2 = %.6f\n', R2)
fprintf('Adj R^2 = %.6f\n', adjR2);
fprintf('RMSE = %.6f MPa\n', RMSE)
%% ---- Plot and Save ------------------------------------------------------
fig = figure; hold on;
plot(epsl, sig, 'k-', 'MarkerFaceColor','k','MarkerSize',2, 'DisplayName','Experimental');
plot(epsl, sigma_fit,'r-', 'LineWidth',1, 'DisplayName','Fitted model');
xlabel('Strain \epsilon');
ylabel('Stress \sigma_d (MPa)');
title(['Fitted Constitutive Model at \epsilon-dot = ', num2str(edot), ' s^{-1}']);
legend show; grid on;
% Add a readable stats box
ax = gca;
xL = xlim(ax); yL = ylim(ax);
txt = {sprintf('R^2 = %.4f', R2), ...
sprintf('Adj R^2 = %.4f', adjR2), ...
sprintf('RMSE = %.3g MPa', RMSE)};
text(xL(1) + 0.02*range(xL), yL(2) - 0.04*range(yL), txt, ...
'VerticalAlignment','top', 'BackgroundColor','w', ...
'Margin',6, 'EdgeColor',[0.1 0.1 0.1], 'FontWeight','bold');
axis padded
end

14 Comments

Thank you for your time and guidance. But I need curve fitting according to provided data. Equation works well, I have taken that equation from another research paper. I just need to fit my data with model equation
But I need curve fitting according to provided data.
Is that different from what my answer proposes? Or do you mean you are not allowed to discard sections of the data, like the linear elastic part, from the fit?
If the latter, it seems futile. There doesn't appear to be any way that your equation can model a piecewise curve containing a linear elastic region at low epsl. If you think it can, show us a choice of parameters E,A,B,m,n from the paper that does so.
Why would it even be beneficial if you could? You know from Hooke's law that that part of the curve should be linear, so why try to approximate it with a nonlinear model?
Yes. Your it is different. I want to get elastic region too in the curve. I have to design another model.
I have to design another model.
Can't you just add a linear piece to the model? Example:
file = 'data.xlsx';
[epsl,sig]=readvars(file) ;
sig=sig*1000;% convert GPa -> MPa
% keep only data that is finite and substantially <1
good = isfinite(epsl) & isfinite(sig) & eps>0 & epsl<0.981;
epsl = epsl(good);
sig = sig(good);
%% ---- Known strain rates -------------------------------------------------
edot = 0.000617; % test strain rate [s^-1]
edot0 = edot; % reference strain rate [s^-1]
%% ---- Initial guesses & bounds ------------------------------------------
% [A, E, B, m, n, a, b]
p0 = [0.04, 100, 0.03, 0.95, 2.0, -0.05, 0.150,0.15]; % initial params (MPa-based)
hooke=epsl<p0(end);
q=polyfit(epsl(hooke), sig(hooke),1);
p0=[p0,q];
lb = [-0.1, 1.2, -.01, -1, 1, 1, 0.01 ,min(epsl),0,-inf ];
ub = [2, 20, 1, 5, 5, 4.0, 0.5 ,inf ,inf,inf];
%% ---- Fit with lsqcurvefit (Optimization Toolbox) -----------------------
edotRatio=edot/edot0;
model = @(p,eps) constitutive_model(p, eps, edotRatio);
opts = optimoptions('lsqcurvefit','Display','iter','MaxIterations',1000);
[pfit, ~] = lsqcurvefit(model, p0, epsl, sig, lb, ub, opts)
Norm of First-order Iteration Func-count Resnorm step optimality 0 11 32818.8 1.19e+05 1 22 5880.21 0.190567 1.77e+04 Objective function returned complex; trying a new point... 2 33 5880.21 0.183082 1.77e+04 3 44 5003.93 0.00915412 1.5e+04 4 55 3537.19 0.0183082 1.06e+04 5 66 1554.94 0.0366165 4.58e+03 6 77 273.676 0.0732329 766 Objective function returned complex; trying a new point... 7 88 273.676 0.140406 766 8 99 202.263 0.00702032 568 9 110 95.1124 0.0140406 344 10 121 6.97486 0.0280813 70.4 11 132 0.332839 0.0561625 10.9 12 143 0.0509623 0.0466304 1.25 13 154 0.0405019 0.112325 11.3 14 165 0.0340404 0.22465 48 15 176 0.0340404 0.200009 48 16 187 0.0254147 0.0500021 21.5 17 198 0.0212286 0.100004 24.5 18 209 0.0149313 0.0541536 15.5 19 220 0.00862811 0.000406046 0.0636 20 231 0.00785399 0.0750601 0.096 21 242 0.00776553 0.00124691 8.5e-05 22 253 0.00776553 4.58163e-06 1.18e-09 Local minimum found. Optimization completed because the size of the gradient is less than the value of the optimality tolerance.
pfit = 1×10
0.0092 10.5711 0.0027 0.9715 1.0000 2.5000 0.1500 0.1500 0.1936 -0.0191
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
sigma_fit = model(pfit, epsl);
postAnalysis(epsl,sig,pfit,sigma_fit,edot)
Goodness of fit: R^2 = 0.963860 Adj R^2 = 0.963345 RMSE = 0.003300 MPa
%% ===================== Local functions (MUST be at file end) =====================
function sigma_d = constitutive_model(p, epsilon, edotRatio)
[A, E, B, m, n, a, b, c]=deal(p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8));
elastic= (epsilon<=c);
sigmaHooke=p(9)*epsilon(elastic)+p(10);
epsilon=epsilon(~elastic);
one_me = max(1 - epsilon, eps);
% Static part
term1 = A .* (1 - exp(-(E./A) .* epsilon .* (1 - epsilon))).^m;
term2 = B .* (epsilon ./ one_me).^n;
sigma_static = term1 + term2;
% Strain-rate factor
rate_factor = 1 + (a + b .* epsilon) .* log(edotRatio);
sigmaInelastic = sigma_static .* rate_factor;
sigma_d=nan(size(elastic));
sigma_d(elastic)=sigmaHooke;
sigma_d(~elastic)=sigmaInelastic;
end
function postAnalysis(epsl,sig,pfit, sigma_fit,edot)
%% ---- Goodness of fit (R^2, adj. R^2, RMSE) -----------------------------
SSE = sum((sig - sigma_fit).^2);
SST = sum((sig - mean(sig)).^2);
R2 = 1 - SSE/SST;
n = numel(sig);
k = numel(pfit); % number of fitted parameters
adjR2 = 1 - (1 - R2) * (n - 1) / max(n - k - 1, 1);
RMSE = sqrt(SSE / n);
% Print to console
fprintf('\nGoodness of fit:\n');
fprintf('R^2 = %.6f\n', R2)
fprintf('Adj R^2 = %.6f\n', adjR2);
fprintf('RMSE = %.6f MPa\n', RMSE)
%% ---- Plot and Save ------------------------------------------------------
fig = figure; hold on;
plot(epsl, sig, 'k.','MarkerSize',2, 'DisplayName','Experimental');
plot(epsl, sigma_fit,'r-', 'LineWidth',1, 'DisplayName','Fitted model');
xlabel('Strain \epsilon');
ylabel('Stress \sigma_d (MPa)');
title(['Fitted Constitutive Model at \epsilon-dot = ', num2str(edot), ' s^{-1}']);
legend show; grid on;
% Add a readable stats box
ax = gca;
xL = xlim(ax); yL = ylim(ax);
txt = {sprintf('R^2 = %.4f', R2), ...
sprintf('Adj R^2 = %.4f', adjR2), ...
sprintf('RMSE = %.3g MPa', RMSE)};
text(xL(1) + 0.02*range(xL), yL(2) - 0.04*range(yL), txt, ...
'VerticalAlignment','top', 'BackgroundColor','w', ...
'Margin',6, 'EdgeColor',[0.1 0.1 0.1], 'FontWeight','bold');
axis padded
end
Dear sir, thank you for your assistance. I really appreciate your efforts.
You're quite welcome, but since you seem satisfied with the answer, please Accept-click it.
clc
close all
clear all
file = 'PUF28_5mmmin.xlsx';
[epsl,sig]=readvars(file) ;
% sig=sig;% convert MPa -> MPa
% keep only data that is finite and substantially <1
good = isfinite(epsl) & isfinite(sig) & (epsl > 0) & (epsl < 0.981);
epsl = epsl(good);
sig = sig(good);
%% ---- Known strain rates -------------------------------------------------
edot = 0.00308; % test strain rate [s^-1]
edot0 = edot; % reference strain rate [s^-1]
%% ---- Initial guesses & bounds ------------------------------------------
% [A, E, B, m, n, a, b]
p0 = [0.9,500, 0.08, 0.5, 2.0, 0.05, 50,0.07]; % initial params (MPa-based)
hooke=epsl<p0(end);
q=polyfit(epsl(hooke), sig(hooke),1);
p0=[p0,q];
lb = [-0.9, 50, -.01, -1, 1, 1, 0.01 ,min(epsl),0,-inf ];
ub = [5, 500, 2, 3, 2, 4.0, 0.1 ,inf ,inf,inf];
%% ---- Fit with lsqcurvefit (Optimization Toolbox) -----------------------
edotRatio=edot/edot0;
model = @(p,eps) constitutive_model(p, eps, edotRatio);
opts = optimoptions('lsqcurvefit','Display','iter','MaxIterations',1000);
[pfit, ~] = lsqcurvefit(model, p0, epsl, sig, lb, ub, opts)
sigma_fit = model(pfit, epsl);
postAnalysis(epsl,sig,pfit,sigma_fit,edot)
%% ===================== Local functions (MUST be at file end) =====================
function sigma_d = constitutive_model(p, epsilon, edotRatio)
% p = [A, E, B, m, n, a, b, c, slope, intercept]
[A, E, B, m, n, a, b, c] = deal(p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8));
elastic = (epsilon <= c);
sigmaHooke = p(9)*epsilon(elastic) + p(10);
e_in = epsilon(~elastic);
one_me = max(1 - e_in, eps);
% --- CORRECT term1 per paper: m is inside the exponential on (1-e)^m
term1 = A .* (1 - exp(-(E./A) .* e_in .* (one_me).^m));
term2 = B .* (e_in ./ one_me).^n;
sigma_static = term1 + term2;
rate_factor = 1 + (a + b .* e_in) .* log(edotRatio);
sigmaInelastic = sigma_static .* rate_factor;
sigma_d = nan(size(epsilon));
sigma_d(elastic) = sigmaHooke;
sigma_d(~elastic) = sigmaInelastic;
end
function postAnalysis(epsl,sig,pfit, sigma_fit,edot)
%% ---- Goodness of fit (R^2, adj. R^2, RMSE) -----------------------------
SSE = sum((sig - sigma_fit).^2);
SST = sum((sig - mean(sig)).^2);
R2 = 1 - SSE/SST;
n = numel(sig);
k = numel(pfit); % number of fitted parameters
adjR2 = 1 - (1 - R2) * (n - 1) / max(n - k - 1, 1);
RMSE = sqrt(SSE / n);
% Print to console
fprintf('\nGoodness of fit:\n');
fprintf('R^2 = %.6f\n', R2)
fprintf('Adj R^2 = %.6f\n', adjR2);
fprintf('RMSE = %.6f MPa\n', RMSE)
%
%% ---- Plot and Save ------------------------------------------------------
fig = figure; hold on;
plot(epsl, sig, 'b.','MarkerSize',3, 'LineWidth',3, 'DisplayName','Experimental');
plot(epsl, sigma_fit,'r-', 'LineWidth',3, 'DisplayName','Fitted model');
xlabel('Strain \epsilon');
ylabel('Stress \sigma_d (MPa)');
title(['Fitted Constitutive Model at \epsilon-dot = ', num2str(edot), ' s^{-1}']);
legend show; grid on;
% ---- Set axis scaling and ticks ----
axis([0 0.97 0 0.05]); % X: 0–1, Y: 0–0.05
xticks(0:0.1:1); % X increments of 0.02
yticks(0:0.01:0.05); % Y increments of 0.01
% Add a readable stats box
ax = gca;
xL = xlim(ax); yL = ylim(ax);
txt = {sprintf('R^2 = %.4f', R2), ...
sprintf('Adj R^2 = %.4f', adjR2), ...
sprintf('RMSE = %.3g MPa', RMSE)};
text(xL(1) + 0.02*range(xL), yL(2) - 0.04*range(yL), txt, ...
'VerticalAlignment','top', 'BackgroundColor','w', ...
'Margin',6, 'EdgeColor',[0.1 0.1 0.1], 'FontWeight','bold');
end
Dear Matt,
Please aissit me, I am not getting curve fitted
Can't find PUF28_5mmmin.xlsx. Please attach it to your last code presentation.
Both of your new .xlsx file attachments appear to contain identical data. Not sure if that was intentional...
Aside from that, the attached modification seems to work better on the new data:
file = 'data_Copy.xlsx';
%---- Known strain rates -------------------------------------------------
edot = 0.00308; % test strain rate [s^-1]
edot0 = edot; % reference strain rate [s^-1]
% ---- Initial guesses & bounds ------------------------------------------
% [A, E, m, n, a, b, c]
p0 = [0.1, 500, 0.5, 2.0, 0.05, 50,0.1]; % initial params (MPa-based)
% [A, E, m, n, a, b]
lb = [-0.9, 50, -1, 1, 1, 0.01 ];
ub = [5, 500, 3, 2, 4.0, 0.1 ];
epsmax=0.85; %Maximum epsilon to fit
doFit(file, edot,edot0, p0,lb,ub,epsmax)
Goodness of fit: R^2 = 0.997467 Adj R^2 = 0.997432 RMSE = 0.000365 MPa
The old data seems to still work as well:
file = 'data.xlsx';
% ---- Known strain rates -------------------------------------------------
edot = 0.000617; % test strain rate [s^-1]
edot0 = edot; % reference strain rate [s^-1]
% ---- Initial guesses & bounds ------------------------------------------
% [A, E, m, n, a, b, c]
p0 = [0.9,500, 0.5, 2.0, 0.05, 50,0.07]; % initial params (MPa-based)
% [A, E, m, n, a, b]
lb = [-0.1, 1.2, -1, 1, 1, 0.01 ];
ub = [2, 20, 5, 5, 4.0, 0.5 ];
epsmax=0.95; %Maximum epsilon to fit
doFit(file, edot,edot0, p0,lb,ub,epsmax)
Warning: Polynomial is not unique; degree >= number of data points.
Goodness of fit: R^2 = 0.995978 Adj R^2 = 0.995924 RMSE = 0.000712 MPa
Hi Matt,
Thank you for your assistance. I’m a bit confused about why the same code you recently provided doesn’t fit the curve at different strain rates. Which settings should I adjust? When I use another strain rate, I don’t obtain the same curve you showed earlier
To demonstrate problems, please get into the habit of running the code here in the online environment, as I have been doing. A screen shot of the results alone doesn't tell us anything, because we cannot see what has changed in the way you are running the code.
By "another strain rate", do you mean a different .xlsx data set?
One thing that might be relevant to your last question. The known edot and edot0 parameters are not doing anything meaningful in your model, and should probably be removed. All they do is change the fitted values of a and b by a factor of log(edot/edot0). Attached is a version which removes edot,edot0 and also includes a routine to auto-guess the 'c' parameter (so, you no longer have to provide an initial guess or that parameter).
file = 'data_Copy.xlsx';
% [A, E, m, n, a, b]
p0 = [0.1, 500, 0.5, 2.0, 0, 0]; % initial params (MPa-based)
% [A, E, m, n, a, b]
lb = [-0.1, 1.2, -1, 1, -inf, -inf ];
ub = [2, 20, 5, 5, +inf, +inf ];
epsmax=0.85; %Maximum epsilon to fit
doFit(file, p0,lb,ub,epsmax)
Goodness of fit: R^2 = 0.998612 Adj R^2 = 0.998593 RMSE = 0.000270 MPa
%%
file = 'data.xlsx';
% ---- Initial guesses & bounds ------------------------------------------
% [A, E, m, n, a, b]
p0 = [0.9,500, 0.5, 2.0, 0, 0]; % initial params (MPa-based)
% [A, E, m, n, a, b]
lb = [-0.1, 1.2, -1, 1, -inf,-inf ];
ub = [2, 20, 5, 5, +inf, +inf ];
epsmax=0.85; %Maximum epsilon to fit
doFit(file, p0,lb,ub,epsmax)
Goodness of fit: R^2 = 0.994608 Adj R^2 = 0.994526 RMSE = 0.000322 MPa

Sign in to comment.

Categories

Products

Asked:

on 1 Sep 2025

Edited:

on 5 Sep 2025

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!