Asked by Fernando Robert Ferrel Ballestas
on 2 Oct 2019

Hello,

I have a function that depends on 3 parameters. I want to create a database by varying each parameter and for this, I will use three for cycles:

For Wpig=3:0.5:8

For chla=0.6:0.2:0.5

For starch_content=2:4:52

[Wavelength,Ea,Es,b,C_abs,C_sca] = proprad(Wpig,chla,starch_content)

Each evaluated condition generates 6 results (Wavelength, Ea, Es, b_C_abs,C_sca). I want to stock these 6 values for each condition, Do you think I should create a mesh/grid for it? It is important for me to be able to use the database created at the end to interpolate.

Could someone help me? I I will be very grateful for your suggestions and advice. Thank you a lot in advance.

Answer by Guillaume
on 2 Oct 2019

Accepted Answer

Assuming the outputs of proprad are all scalar:

[Wpig, chla, starch_content] = ndgrid(3:0.5:8, 0.6:0.2:0.5, 2:4:52);

[Wavelength, Ea, Es, b, C_abs, C_sca] = arrayfun(@proprad, Wpig, chla, starch_content);

If the outputs are not scalar, then add 'UniformOutput', false to the arrayfun call.

That's also assuming that the proprad function cannot operate directly on array inputs. Otherwise, the arrayfun is not necessary.

Fernando Robert Ferrel Ballestas
on 30 Oct 2019 at 12:57

- Wavelength is not an input of "proprad" , I put it because it has the same dimension of Ea and it could be used for the 4D-matrix construction but I'm not sure. So, you can erase/forget this vector.
- "proprad" evaluates only scalar inputs, so we need to use "for" cycles in order to evaluate all the conditions.

First of all, I think I need to create a grid for all the possible conditions, giving something like this:

[X,Y,Z] = ndgrid(Wpig,Chla,Starch);

I would need help for the next parts: generate the 4D-Matrix, knowing that for each point (X,Y,Z) I obtain a vector (Ea) from my function "proprad".

If necessary, Wpig, Chla, Starch can have the same dimension. I must respect only the bounds of these vectors.

Thank you a lot one more time!

Guillaume
on 30 Oct 2019 at 14:02

You can use arrayfun and ndgrid as I initially answered:

Wpig = 0.5:0.5:7;

Chla = 0.5:0.01:0.6;

Starch = 0:0.04:0.24;

[Wpig3D, Chla3D, Starch3D] = ndgrid(Wpig, Chla, Starch); %creates 3D matrices

reshapefun = @(w, c, s) reshape(proprad(w, c, s), 1, 1, 1, []); %function to move the vector output of proprad into the 4th dimension

Ea = cell2mat(arrayfun(reshapefun, Wpig3D, Chla3D, Starch3D, 'UniformOutput', false)); %create 3D cell arrays of vectors and convert to matrix

If proprad can directly return a 1x1x1xN vector, then you don't need the reshapefun and can directly do:

Ea = cell2mat(arrayfun(@proprad, Wpig3D, Chla3D, Starch3D, 'UniformOutput', false)); %create 3D cell arrays of vectors and convert to matrix

which will run faster.

Or you can use a loop indeed, which may be faster:

Wpig = 0.5:0.5:7;

Chla = 0.5:0.01:0.6;

Starch = 0:0.04:0.24;

Ea = zeros(numel(Wpig), numel(Chla), numel(starch), 31);

for sidx = 1:numel(Starch)

for cidx = 1:numel(Chla)

for widx = 1:numel(Wpig)

Ea(widx, cidx, sidx, :) = proprad(Wpig(widx), Chla(cidx), Starch(sidx));

end

end

end

Either way, once you've got the 4D matrix, it's easy to interpolate, ndgrid your 4 dimensions (Wpig, Chla, Starch and Wavelength), then build your interpolant with griddedInterpolant and query it at whichever points you want:

Wpig = 0.5:0.5:7;

Chla = 0.5:0.01:0.6;

Starch = 0:0.04:0.24;

Wavelength = linspace(300,700,31);

[Wpig4d, Chla4D, Starch4D, Wavelength4D] = ndgrid(Wpig, Chla, Starch, Wavelength);

%build interpolant

Finterp = griddedInterpolant(Wpgid4D, Chla4D, Starch4D, Wavelength4D, Ea);

%query interpolant for wpig = .93, Chla = 0.57, Starch = 0.12 at all wavelengths:

result = Finterp([repmat([.93, .57, .12], numel(Wavelength), 1), Wavelength(:)])

Fernando Robert Ferrel Ballestas
on 30 Oct 2019 at 17:48

Great!!! That's working perfect!

Thank you a lot!

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.