Regarding diagrv for array

Hello:

I wanted to check, whether the diagrv( ) command is compatible to be used with an array? For example I have a 5 by 3 by 3 array and I want to replace the diagonal elements of all the 5 by 3 by 3 matrices with 1, is there a function to do that, without using loop?

Thanks a lot

Annesha

 

 

 

1 Answer



0



There is not a built-in procedure to do it, but here are a couple of procedures that will do it for you. The first one uses a loop, the second one does not.

a = areshape(rndn(3*5*5, 1), 3|5|5);

a_1 = aDiagrv(a, 1);

d = { 1, 2, 3, 4, 5 };
a_2 = aDiagrv(a, d);

proc (1) = aDiagrv(a, d);
    local i, ord, n_mats, min_mat_dim;
    
    //Get dimensions of array
    ord = getorders(a);
    
    //Get number of matrices
    n_mats = prodc(ord[1:rows(ord)-2]);
    
    //Get smallest of trailing two dimensions
    min_mat_dim = minc(ord[rows(ord)]  | ord[rows(ord)-1]);
    
    //Apply 'diagrv' to each matrix in the array
    for i(1, n_mats, 1);
        a[i,.,.] = diagrv(arraytomat(a[i,.,.]), reshape(d, min_mat_dim, 1));
    endfor;
    
    retp(a);
endp;
a = areshape(rndn(3*6*8, 1), 3|6|6);
aDiagrv(a, 1);

//Adds a scalar or vector to the diagonals
//Only supports arrays where the last two
//dimensions are the same
proc aDiagrv2(a, d);
    local ord, idx, n_mats,a_cols;
    
    //Get dimensions of array
    ord = getorders(a);
    
    //Get number of matrices
    n_mats = prodc(ord[1:rows(ord)-2]);
    
    //Get smallest of trailing two dimensions
    a_cols = ord[rows(ord)];
    
    //Make 'a' into a column vector by row
    a = vecr(a);
    
    //Get indices for diagonal elements of the first matrix
    idx = seqa(1, a_cols+1, a_cols);
    
    //Create indices for diagonal of all matrices
    idx = vecr(reshape(idx, n_mats, a_cols) + seqa(0, a_cols.^2, n_mats));
    
    //Assign elements of 'd' to 'a'
    a[idx] = reshape(d, rows(idx), 1);
    
    //Reshape 'a' to it's original form and return
    retp(areshape(a, ord));
endp;

aptech

1,773

Your Answer

1 Answer

0

There is not a built-in procedure to do it, but here are a couple of procedures that will do it for you. The first one uses a loop, the second one does not.

a = areshape(rndn(3*5*5, 1), 3|5|5);

a_1 = aDiagrv(a, 1);

d = { 1, 2, 3, 4, 5 };
a_2 = aDiagrv(a, d);

proc (1) = aDiagrv(a, d);
    local i, ord, n_mats, min_mat_dim;
    
    //Get dimensions of array
    ord = getorders(a);
    
    //Get number of matrices
    n_mats = prodc(ord[1:rows(ord)-2]);
    
    //Get smallest of trailing two dimensions
    min_mat_dim = minc(ord[rows(ord)]  | ord[rows(ord)-1]);
    
    //Apply 'diagrv' to each matrix in the array
    for i(1, n_mats, 1);
        a[i,.,.] = diagrv(arraytomat(a[i,.,.]), reshape(d, min_mat_dim, 1));
    endfor;
    
    retp(a);
endp;
a = areshape(rndn(3*6*8, 1), 3|6|6);
aDiagrv(a, 1);

//Adds a scalar or vector to the diagonals
//Only supports arrays where the last two
//dimensions are the same
proc aDiagrv2(a, d);
    local ord, idx, n_mats,a_cols;
    
    //Get dimensions of array
    ord = getorders(a);
    
    //Get number of matrices
    n_mats = prodc(ord[1:rows(ord)-2]);
    
    //Get smallest of trailing two dimensions
    a_cols = ord[rows(ord)];
    
    //Make 'a' into a column vector by row
    a = vecr(a);
    
    //Get indices for diagonal elements of the first matrix
    idx = seqa(1, a_cols+1, a_cols);
    
    //Create indices for diagonal of all matrices
    idx = vecr(reshape(idx, n_mats, a_cols) + seqa(0, a_cols.^2, n_mats));
    
    //Assign elements of 'd' to 'a'
    a[idx] = reshape(d, rows(idx), 1);
    
    //Reshape 'a' to it's original form and return
    retp(areshape(a, ord));
endp;

You must login to post answers.

Have a Specific Question?

Get a real answer from a real person

Need Support?

Get help from our friendly experts.