0
votes

I have a matrix which has dimension 5-by-4 whose elements are a function of 2 parameters beta1 and beta2, which takes on 50 values each.

The 5-by-4 matrix has the form

for i=1:5
   factors(i,:)=  [1,...
                  1-exp(-terms(i)/beta1) /(terms(i)/beta1), ...
                  (1-exp(-terms(i)/beta1))/(terms(i)/beta1)-exp(-terms(i)/beta1), ...
                  (1-exp(-terms(i)/beta2))/(terms(i)/beta2)-exp(-terms(i)/beta2)];
end

I want to create a larger matrix whose columns contain 50 of the 5-by-4 matrices with varying beta1 and fixed beta2. The rows contain 50 of the 5-by-4 matrices with varying beta2 and fixed beta1. So the dimensions of the larger matrix are 250-by-200.

Is there a function or loop which can help me with this? I've been stuck on this for a long time.

3
How are the elements function of beta? you have a function()? - Ander Biguri
for i=1:5 factors(i,:)=[1, (1-exp(-terms(i)/beta1)/(terms(i)/beta1)), (1-exp(-terms(i)/beta1))/ (terms(i)/beta1)-exp(-terms(i)/beta1), (1-exp(-terms(i)/beta2))/(terms(i)/beta2)-exp(-terms(i)/beta2)]; end - A1122
Do you simply need to replicate the 5 by 4 matrix 50 times and stack them together? Or do each element of the larger matrix need to be re-evaluated by your function? i.e. your function should now be i = 1:250 ? - GameOfThrows

3 Answers

0
votes

I'm assuming you have or can write a function that accepts two parameters and output your 5-by-4 matrix i.e.

function m = f(beta1, beta2) %// You must write f yourself. m is a 5-by-4 matrix

then the simplest solution would just be to create a nested loop (preallocating for efficiency of course). Note that I am also assuming you know how you want to vary beta1 and beta2 and that you will put these in 50-by-1 vectors B1 and B2 yourself:

M = zeros(250,200);
b1 = 1;
for r = 1:5:(250-5)
    b2 = 1;
    for c = 1:4:(200-4)
        M(r:r+4,c:c+3) = f(B1(b1), B2(b2));
        b2 = b2+1;
    end
    b1 = b1+1;
end
0
votes

Say I have a value that depends on 2 other values. I can write a function to calculate this say myfun = @(x,y) x + y. I can use that with arrayfun or bsxfun, etc to rapidly calculate values for all x's and y's.

x = rand(1000,1);
y = rand(1000,1);
res = arrayfun(myfun, x, y);

In your case you need to define terms ahead of time and then vary beta1 and beta2 as desired. One thing to look out for is that arrayfun wants all the variables to be of the same size so use repmat or similar to reshape beta1 and beta2. For example

terms = 1:5;
i = 1:5;
myfun = @(beta1, beta2) [1, (1-exp(-terms(i)/beta1)/(terms(i)/beta1)), (1-exp(-terms(i)/beta1))/ (terms(i)/beta1)-exp(-terms(i)/beta1), (1-exp(-terms(i)/beta2))/(terms(i)/beta2)-exp(-terms(i)/beta2)];
beta1 = repmat(rand(1,1),1,5);
beta2 = repmat(rand(1,1),1,5);
results = arrayfun(myfun, beta1, beta2,i,'UniformOutput',0);

The output of this will be a cell of arrays. I believe under the hood arrayfun is just a loop but it should be vectorized by MathWorks so it should be fast.

To create varying beta1 and fixed beta2 just define them as such were beta1 varies for the first half of the vector and is fixed for the second half. For example:

beta1 = ones(250,1) * 10;
beta1(1:125) = 1:125;

and so on.

0
votes

Here is an explicit example that generalizes and is verified easily to give the correct result. Just change the definition of m0 to your 5x4 matrix:

%define beta variables as parameter lists:
beta1 = linspace(10,40,4);
beta2 = linspace(1,4,4);
L1    = length(beta1);
L2    = length(beta2);

%define m0 as your 5x4 matrix:
m0 = @(b1,b2)[b1, b2, 0 ; 0, 0, 0];
m = zeros(size(m0(1,1)));
[nrows,ncols] = size(m);

for q1 = 1:L1
    for q2 = 1:L2

        rows = (1:nrows) + (q2-1)*nrows;
        cols = (1:ncols) + (q1-1)*ncols;
        m(rows,cols) = m0(beta1(q1),beta2(q2));
    end
end

m0(10,1)
m