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;
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;