我的主脚本包含以下代码:
%# Grid and model parameters
nModel=50;
nModel_want=1;
nI_grid1=5;
Nth=1;
nRow.Scale1=5;
nCol.Scale1=5;
nRow.Scale2=5^2;
nCol.Scale2=5^2;
theta = 90; % degrees
a_minor = 2; % range along minor direction
a_major = 5; % range along major direction
sill = var(reshape(Deff_matrix_NthModel,nCell.Scale1,1)); % variance of the coarse data matrix of size nRow.Scale1 X nCol.Scale1
%# Covariance computation
% Scale 1
for ihRow = 1:nRow.Scale1
for ihCol = 1:nCol.Scale1
[cov.Scale1(ihRow,ihCol),heff.Scale1(ihRow,ihCol)] = general_CovModel(theta, ihCol, ihRow, a_minor, a_major, sill, 'Exp');
end
end
% Scale 2
for ihRow = 1:nRow.Scale2
for ihCol = 1:nCol.Scale2
[cov.Scale2(ihRow,ihCol),heff.Scale2(ihRow,ihCol)] = general_CovModel(theta, ihCol/(nCol.Scale2/nCol.Scale1), ihRow/(nRow.Scale2/nRow.Scale1), a_minor, a_major, sill/(nRow.Scale2*nCol.Scale2), 'Exp');
end
end
%# Scale-up of fine scale values by averaging
[covAvg.Scale2,var_covAvg.Scale2,varNorm_covAvg.Scale2] = general_AverageProperty(nRow.Scale2/nRow.Scale1,nCol.Scale2/nCol.Scale1,1,nRow.Scale1,nCol.Scale1,1,cov.Scale2,1);
我在主脚本中使用了两个函数,general_CovModel()
和general_AverageProperty()
,它们如下所示:
function [cov,h_eff] = general_CovModel(theta, hx, hy, a_minor, a_major, sill, mod_type)
% mod_type should be in strings
angle_rad = theta*(pi/180); % theta in degrees, angle_rad in radians
R_theta = [sin(angle_rad) cos(angle_rad); -cos(angle_rad) sin(angle_rad)];
h = [hx; hy];
lambda = a_minor/a_major;
D_lambda = [lambda 0; 0 1];
h_2prime = D_lambda*R_theta*h;
h_eff = sqrt((h_2prime(1)^2)+(h_2prime(2)^2));
if strcmp(mod_type,'Sph')==1 || strcmp(mod_type,'sph') ==1
if h_eff<=a
cov = sill - sill.*(1.5*(h_eff/a_minor)-0.5*((h_eff/a_minor)^3));
else
cov = sill;
end
elseif strcmp(mod_type,'Exp')==1 || strcmp(mod_type,'exp') ==1
cov = sill-(sill.*(1-exp(-(3*h_eff)/a_minor)));
elseif strcmp(mod_type,'Gauss')==1 || strcmp(mod_type,'gauss') ==1
cov = sill-(sill.*(1-exp(-((3*h_eff)^2/(a_minor^2)))));
end
和
function [PropertyAvg,variance_PropertyAvg,NormVariance_PropertyAvg]=...
general_AverageProperty(blocksize_row,blocksize_col,blocksize_t,...
nUpscaledRow,nUpscaledCol,nUpscaledT,PropertyArray,omega)
% This function computes average of a property and variance of that averaged
% property using power averaging
PropertyAvg=zeros(nUpscaledRow,nUpscaledCol,nUpscaledT);
%# Average of property
for k=1:nUpscaledT,
for j=1:nUpscaledCol,
for i=1:nUpscaledRow,
sum=0;
for a=1:blocksize_row,
for b=1:blocksize_col,
for c=1:blocksize_t,
sum=sum+(PropertyArray((i-1)*blocksize_row+a,(j-1)*blocksize_col+b,(k-1)*blocksize_t+c).^omega); % add all the property values in 'blocksize_x','blocksize_y','blocksize_t' to one variable
end
end
end
PropertyAvg(i,j,k)=(sum/(blocksize_row*blocksize_col*blocksize_t)).^(1/omega); % take average of the summed property
end
end
end
%# Variance of averageed property
variance_PropertyAvg=var(reshape(PropertyAvg,...
nUpscaledRow*nUpscaledCol*nUpscaledT,1),1,1);
%# Normalized variance of averageed property
NormVariance_PropertyAvg=variance_PropertyAvg./(var(reshape(...
PropertyArray,numel(PropertyArray),1),1,1));
问题:使用Matlab,我想通过扰动/改变以下任何(或全部)变量来优化covAvg.Scale2
,使其与cov.Scale1
紧密匹配
1)a_minor
2)a_major
3)theta
我知道我可以使用fminsearch
,但是,在使用fminsearch
时,我无法干扰我想要的变量。
我不会假装理解你正在做的一切。但这听起来像是一个典型的最小化问题。您想要做的是生成一个以a_minor
、a_major
和theta
为参数的函数,并返回covAvg.Scale2
和cov.Scale1
之间的差的平方。类似这样的东西:
function diff = minimize_me(a_minor, a_major, theta)
... your script goes here
diff = (covAvg.Scale2 - cov.Scale1)^2;
end
然后你需要matlab来最小化这个函数。这里有不止一个选项。由于只有三个变量可以最小化,因此fminsearch
是一个很好的起点。你可以这样称呼它:
opts = optimset('display', 'iter');
x = fminsearch( @(x) minimize_me(x(1), x(2), x(3)), [a_minor_start a_major_start theta_start], opts)
fminsearch
的第一个参数是要优化的函数。它必须采用一个参数:一个将被扰动的变量向量,以便找到最小值。在这里,我使用一个匿名函数从这个向量中提取值,并将它们传递到minimize_me
中。fminsearch
的第二个参数是一个向量,包含要开始搜索的值。第三个参数是影响搜索的选项;当您第一次开始优化时,最好将display
设置为iter
,这样您就可以了解优化器的收敛情况。
如果您的参数有限制域(例如,它们必须都是正的),请查看文件交换上的fminsearchbnd
。
如果我误解了你的问题,而这根本没有帮助,试着发布我们可以自己运行来重现问题的代码。