MATLAB Answers

how can I save the data generated from a function that depends on 3 parameters

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.


Sign in to comment.


1 Answer

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.


  • 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!
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));
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(:)])

Sign in to comment.