2

我觉得我在生成部分变化的块对角网格的解决方案中缺少一些直观的东西。无论如何,我想摆脱我的函数中的循环(为了挑战......)

给定参数元组、区间数和百分比变化:

params = [100 0.5   1
           24   1 0.9];
nint   = 1; 
perc   = 0.1;

所需的输出应该是:

pspacegrid(params,perc,nint)
ans =
   90.0000    0.5000    1.0000
  100.0000    0.5000    1.0000
  110.0000    0.5000    1.0000
  100.0000    0.4500    1.0000
  100.0000    0.5000    1.0000
  100.0000    0.5500    1.0000
  100.0000    0.5000    0.9000
  100.0000    0.5000    1.0000
  100.0000    0.5000    1.1000
   21.6000    1.0000    0.9000
   24.0000    1.0000    0.9000
   26.4000    1.0000    0.9000
   24.0000    0.9000    0.9000
   24.0000    1.0000    0.9000
   24.0000    1.1000    0.9000
   24.0000    1.0000    0.8100
   24.0000    1.0000    0.9000
   24.0000    1.0000    0.9900

您可以看到变化发生在此掩码表示的值处:

mask =
     1     0     0
     1     0     0
     1     0     0
     0     1     0
     0     1     0
     0     1     0
     0     0     1
     0     0     1
     0     0     1
     1     0     0
     1     0     0
     1     0     0
     0     1     0
     0     1     0
     0     1     0
     0     0     1
     0     0     1
     0     0     1

功能pspacegrid()是:

function out = pspacegrid(params, perc, nint)
% PSPACEGRID Generates a parameter space grid for sensitivity analysis

% Size and number of variation steps
sz     = size(params);
nsteps = nint*2+1;

% Preallocate output
out    = reshape(permute(repmat(params,[1,1,nsteps*sz(2)]),[3,1,2]),[],sz(2));

% Mask to index positions where to place interpolated 
[tmp{1:sz(2)}] = deal(true(nsteps,1));
mask           = repmat(logical(blkdiag(tmp{:})),sz(1),1);

zi = cell(sz(1),1);
% LOOP per each parameter tuple
for r = 1:sz(1)
    % Columns, rows, rows to interpolate and lower/upper parameter values
    x     = 1:sz(2);
    y     = [1; nint*2+1];
    yi    = (1:nint*2+1)';
    z     = [params(r,:)*(1-perc); params(r,:)*(1+perc)];
    % Interpolated parameters 
    zi{r} = interp2(x,y,z, x, yi);
end
out(mask) = cat(1,zi{:});
4

1 回答 1

1

我想我明白了,建立了你的预循环代码:

params = [100 0.5   1
           24   1 0.9];
nint   = 1; 
perc   = 0.1;

sz     = size(params);
nsteps = nint*2+1;

% Preallocate output
out    = reshape(permute(repmat(params,[1,1,nsteps*sz(2)]),[3,1,2]),[],sz(2));

%Map of the percentage moves
[tmp{1:sz(2)}] = deal(linspace(-perc,perc,nint*2+1)');
mask = repmat(blkdiag(tmp{:}),sz(1),1) + 1; %Add one so we can just multiply at the end

mask.*out

因此,不是让你的面具复制我让它复制每个元素所做的百分比移动,这是一个重复模式,基本元素是这样制作的:

linspace(-perc,perc,nint*2+1)'

然后它就像添加1到整个事物并乘以out矩阵一样简单

我对其进行了如下测试:

me = mask.*out;
you = pspacegrid(params, perc, nint);

check = me - you < 0.0001;

mean(check(:))

当我摆弄输入时似乎工作。但是我确实收到了您的功能错误,我不得不更改true(...)ones(...). 这可能是因为我在线运行它可能使用 Octave 而不是 Matlab。

于 2013-08-08T14:34:01.227 回答