Trying to use fminsearch but always says "Unable to perform assignment because the size of the left side is 1-by-1 and the size of the right side is 1-by-2821"
2 views (last 30 days)
Show older comments
Saeid Bina
on 12 Nov 2019
Commented: Saeid Bina
on 12 Nov 2019
I have very simple code and works well manually and I can fit with actual data. Could you please help me with this? I stuck a week! I want to optimaize Par which includs three number. tau and Tfm_mis are measured minutes and measured data, respectively.
Any help is severly appreciated.
Function:
function [RMSE,Tfm_MLS] = MLS_fit1(par,tau,Tfm_mis)
%Tfm_MLS are our calculated data in timely basis
%Input constants
rho_s = 2533; %[kg/mc]
c_s = 840; %[J/kg.K]
eps = 0.367;
T_0 = 12;
rho_w = 1020; %water density [kg/mc]
c_w = 4186;
r_bh= 0.076; %borehole ID/OD=151/165
q=56.53; %[W/m]
%equations from here and by using above data
C_0 = rho_s*c_s*(1-eps)+rho_w*c_w*eps;
est = r_bh^2*C_0/4*tau*par(1);
f=(1./est).*exp((-1./est)-((par(2)^2)*c_w^2*r_bh^2*rho_w^2)/16*par(1));
T=cumtrapz(est,f);
f=(1./est).*exp((-1./est)-((par(2)^2)*c_w^2*r_bh^2*rho_w^2)/16*par(1));
T=cumtrapz(est,f);
dteta= 45*pi/180;
teta =(dteta : dteta : 2*pi);
z = q./(4*pi*par(1)).*exp((par(2).*rho_w.*c_w.*r_bh.*cos(teta))./2.*par(1));
g=T*z;
A=mean(g');
B = T_0+A;
Tfm_MLS= B + (q * par(3));
%Objective
%Tfm_mis are our measured data and tau are their time (minute)
RMSE = (sum((Tfm_MLS-Tfm_mis).^2)/length(tau).^0.5);
end
script:
close all, clear all, clc
load TRT_Grouted.txt
[min,n]=size(TRT_Grouted);
t_in=60;
t_end=2880;
tau = TRT_Grouted(t_in:t_end,1);
Tfm_mis = TRT_Grouted(t_in:t_end,2);
par=[1.5,1E-5,0.03];
options= optimset('Display', 'iter');
[par,RMSE] = fminsearch(@(par) MLS_fit1(par,tau,Tfm_mis), par, options);
4 Comments
Walter Roberson
on 12 Nov 2019
By the way notice you have repeated lines
f=(1./est).*exp((-1./est)-((par(2)^2)*c_w^2*r_bh^2*rho_w^2)/16*par(1));
T=cumtrapz(est,f);
f=(1./est).*exp((-1./est)-((par(2)^2)*c_w^2*r_bh^2*rho_w^2)/16*par(1));
T=cumtrapz(est,f);
Accepted Answer
Walter Roberson
on 12 Nov 2019
g=T*z;
That is 2821 x 1 * 1 x 8, giving 2821 x 8.
A=mean(g');
The transpose gives 8 x 2821. The mean proceeds along the first non-singular dimension, so gives 1 x 2821.
B = T_0+A;
Tfm_MLS= B + (q * par(3));
Tfm_MLS is 1 x 2821
RMSE = (sum((Tfm_MLS-Tfm_mis).^2)/length(tau).^0.5);
Tfm_MLS is 1 x 2821. Tfm_mis (from input) is 2821 x 1. Before R2016b, subtracting those would give an error; now it gives a 2821 x 2821 result. sum() of that along one dimension gives a 1 x 2821 result, which is not what you want to be returned.
You should be using
A = mean(g, 2);
which will give a 2821 x 1 result.
However, I recommend you reconsider the mathematics more. When you take 2821 x 1 * 1 x 8 and then take the mean() along the second dimension, then the result is equivalent to 2821 x 1 * mean(1 x 8) -- that is you could skip steps by using
A = T .* mean(z,2);
where mean(z,2) would be a scalar.
2 Comments
Walter Roberson
on 12 Nov 2019
T is our tempreture at each minute and z is each angle and I needed to multiply each minute to each 8 angle.
Then calculate the average of all angles.
That is the same as multiplying the temperatures by the average over the angles, instead of having to take the average of (temperature times angle), Taking mean(z,2) once and multiplying the temperatures by that would be much more efficient than what you are doing now.
More Answers (1)
Saeid Bina
on 12 Nov 2019
4 Comments
KALYAN ACHARJYA
on 12 Nov 2019
Edited: KALYAN ACHARJYA
on 12 Nov 2019
No, just mention this link on second question(if it is related and helped to answer the question)
Be specific always? Keep Learning!
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!