0

My main script contains following code:

%# 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);

I am using two functions, general_CovModel() and general_AverageProperty(), in my main script which are given as following:

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

and

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)); 

Question: Using Matlab, I would like to optimize covAvg.Scale2 such that it matches closely with cov.Scale1 by perturbing/varying any (or all) of the following variables

1) a_minor

2) a_major

3) theta

I am aware I can use fminsearch, however, how I am not able to perturb the variables I want to while using this fminsearch.

Stewie Griffin
  • 14,889
  • 11
  • 39
  • 70
  • I was about to post a big answer that amounted to "use `fminsearch`" ;-) Why can't you use `fminsearch`? Can't you just create a single function that returns the square (or absolute value) of the difference between your two scales, and that takes your three parameters as arguments, and then use `fminsearch` to minimize that function? – Dan Becker Nov 15 '12 at 17:32
  • @Dan: This is how I used the `fminsearch`: `covScales = cat(3, cov.Scale1, covAvg.Scale2); misfit = fminsearch(@covOptimization,covScales);`...where the function `covOptimization` is defined as following: `function [misfit] = covOptimization(covScales); error = covScales(:,:,1) - covScales(:,:,2); misfit = norm(error,2);`. I didn't post this to avoid overwhelming with different codes. –  Nov 15 '12 at 17:49
  • OK, I think I understand, will post my answer – Dan Becker Nov 15 '12 at 22:01

1 Answers1

2

I won't pretend to understand everything that you are doing. But it sounds like a typical minimization problem. What you want to do is to come up with a single function that takes a_minor, a_major and theta as arguments, and returns the square of the difference between covAvg.Scale2 and cov.Scale1. Something like this:

function diff = minimize_me(a_minor, a_major, theta)
    ... your script goes here
    diff = (covAvg.Scale2 - cov.Scale1)^2;
end

Then you need matlab to minimize this function. There's more than one option here. Since you only have three variables to minimize over, fminsearch is a good place to start. You would call it something like this:

opts = optimset('display', 'iter');
x = fminsearch( @(x) minimize_me(x(1), x(2), x(3)), [a_minor_start a_major_start theta_start], opts)

The first argument to fminsearch is the function you want to optimize. It must take a single argument: a vector of the variables that will be perturbed in order to find the minimum value. Here I use an anonymous function to extract the values from this vector and pass them into minimize_me. The second argument to fminsearch is a vector containing the values to start searching at. The third argument are options that affect the search; it's a good idea to set display to iter when you first start optimizing, so that you can get an idea of well the optimizer is converging.

If your parameters have restricted domains (e.g. they must all be positive) take a look at fminsearchbnd on the file exchange.

If I have misunderstood your problem, and this doesn't help at all, try posting code that we can run to reproduce the problem ourselves.

Dan Becker
  • 1,196
  • 10
  • 18
  • Hi Dan: Thanks for your answer. I was busy with something else, therefore, I took time responding to your answer. I am sorry about that. I make the function `minimize_me` as you suggested and then call the 2 lines of code you have at the bottom, I get following error: `??? Subscripted assignment dimension mismatch. Error in ==> fminsearch at 195 fv(:,1) = funfcn(x,varargin{:});`. Do you know what's wrong? –  Nov 17 '12 at 21:32
  • Yes, I've seen that error myself. I don't remember what causes it, but I think it indicate a problem with the first argument to `fminsearch`. Maybe try turning that anonymous function into a real function, and then make sure you can call it without errors. – Dan Becker Nov 18 '12 at 02:14
  • Ah! Another idea ... it may mean that you have the wrong number of elements in the initial value vector (i.e. the second argument to `fminsearch`). – Dan Becker Nov 18 '12 at 02:15
  • Dan: I am not using anonymous function anywhere. The function `minimize_me` is a separate function file. Regarding your last comment, the 2nd argument (for that matter all arguments) to `fminsearch` are scalars. –  Nov 18 '12 at 03:15
  • Not sure what you mean by "the 2nd argument ... to fminsearch are scalars". But the first argument to `fminsearch` should be a function that takes a single vector as argument, and the second argument to `fminsearch` is a vector of the same length as you pass into the function for the 1st argument. – Dan Becker Nov 18 '12 at 04:09
  • If this still doesn't help, try posting all of your code, maybe as a gist or pastebin or something. Hard to help more unless we see exactly what you are doing. – Dan Becker Nov 18 '12 at 04:10
  • Dan: Look at my most recent question on this error: http://stackoverflow.com/questions/13435836/matlab-error-while-using-fminsearch –  Nov 18 '12 at 04:13
  • Huh, that looks OK to me. No access to MATLAB right now, I'll look at it tomorrow afternoon if no one else has figured it out by then. – Dan Becker Nov 18 '12 at 04:17
  • @ Dan: I found the answer. I missed the criterion for `fminsearch` where it says `fminsearch` **finds the minimum of a scalar function**. So, I took the `norm` of the difference in covariance values. That helped in running the code. Thanks for your other answer though! –  Nov 18 '12 at 19:38