cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Your Friends List is a way to easily have access to the community members that you interact with the most! X

Is there a way to extract a specific range of rows and columns from a matrix?

sfan
1-Newbie

Is there a way to extract a specific range of rows and columns from a matrix?

In Matlab, when I plan to extract a submatrix from a large matrix in the following situation:

Capture.JPG

Say I want to extract row and column 1 and 4 from K, I can create an index matrix and do this:

idx = [4 1; 1 2; 2 3; 3 5];

k = K(idx(1,:),idx(1,:));

But in Mathcad, the built in function submatrix can only extract continuous row and column ranges.

Is there a way to let Mathcad do the same job as in Matlab?

Best

Shawn

1 ACCEPTED SOLUTION

Accepted Solutions
Werner_E
24-Ruby V
(To:sfan)

So far I guess the following should help. You can extract the appropriate row of your idx matrix using Primes row selector.

View solution in original post

15 REPLIES 15
LucMeekes
23-Emerald III
(To:sfan)

That is not supported as a built in function. You can program it though.

Luc

JeffH1
14-Alexandrite
(To:sfan)
Werner_E
24-Ruby V
(To:sfan)

Say I want to extract row and column 1 and 4 from K,

You are not just looking for the extraction of a single matrix element, or are you?

Or do you really mean what you write - extracting the full first and fourth column and also the first and fourth row. This would mean that in your example you want to extract 16 values and four of them would be extracted twice. If that is what you are after, you would have to tell us in which way you would like the 16 (or 12) value being arranged - which data structure.

In case you are looking for a way to extract a couple of matrix elements whose indices are given by a matrix "idx" and collect those elements in a vector, the following two methods should help. Otherwise you would have to come back and specify more detailed what kind of result you are expecting.

BTW, the value 5 in your idx matrix seems to be wrong anyway, even if you set ORIGIN to 1.

StuartBruff
23-Emerald II
(To:Werner_E)

Werner Exinger wrote:

Say I want to extract row and column 1 and 4 from K,

You are not just looking for the extraction of a single matrix element, or are you?

Or do you really mean what you write - extracting the full first and fourth column and also the first and fourth row. This would mean that in your example you want to extract 16 values and four of them would be extracted twice. If that is what you are after, you would have to tell us in which way you would like the 16 (or 12) value being arranged - which data structure.

In case you are looking for a way to extract a couple of matrix elements whose indices are given by a matrix "idx" and collect those elements in a vector, the following two methods should help. Otherwise you would have to come back and specify more detailed what kind of result you are expecting.

BTW, the value 5 in your idx matrix seems to be wrong anyway, even if you set ORIGIN to 1.

‌5 would be wrong as an index into K as given; however, the example he gives is the Cartesian product of the first row of idx (that is, combinations of 4 and 1), so Matlab will return a 2x2 array of those elements.  I've got a few functions that will do vaguely what he wants ... I'll dig them out tomorrow when I've got access to the PC I've got them on.I

A Proper indexing system would be so helpful in cases like this. 😞

Stuart

Thank you, Stuart.

I posted a similar question before and I remember you answered me on that.

I really appreciate that.

For this homework, I used Matlab to assemble the matrix and it is pretty handy that in Mathcad Prime I can paste the matlab code to demonstrate the process.

Sorry that I lost the function you gave me last time, I changed my computer but I have created a folder in One Drive so that I can always keep the helps from community back up.

I would agree on that Matlab is more flexible in terms of programming, but this semester after my professor pushes the request for units, I found Mathcad really powerful.

Luckily I am not doing Finite Element in Mathcad so that I don't have to assembly a lot.

Thank you guys so much for sparing your time helping the community grow!

Best

Shawn

Ah, so you think he is looking for something like this?

sfan
1-Newbie
(To:Werner_E)

Hi, Werner,

Sorry I truncate the original problem that results in some confusion.

The original one is this:

Capture.JPG

Thus there are 10 DOFs.

With Matlab, I can do this to assemble the matrix:

k = @(L,EI) [12 -12 6*L 6*L;
            -12 12 -6*L -6*L;
            6*L -6*L 4*L^2 2*L^2;
            6*L -6*L 2*L^2 4*L^2]*EI/L^3; % Beam Local Stiffness Matrix

k1 = k(1/4,1); % beam local stiffness matrice
% Assume EI=1, L=1/4;

K = zeros(10,10); % In total there are 10 DOFs
idxc = [4 1 9 6;
        1 2 6 7;
        2 3 7 8;
        3 5 8 10];
% Index for beam elemental DOFs

for i = 1:4 % Assemble global beam stiffness matrix
    K(idxc(i,:),idxc(i,:)) = K(idxc(i,:),idxc(i,:)) + k1;
end

Ktt = K(1:5,1:5) - (K(6:10,1:5))'*(K(6:10,6:10))^-1*K(6:10,1:5);
%Stiffness Condensation

Ktt = Ktt(1:3,1:3); % Subtract Boundary Conditions & Rotational DOFs

Here idxc stores all the 4 DOFs for each element, with the DOFs not continuous labeled.

In Mathcad, however, the built in function submatrix cannot work in this way.

Hope this clarify the problem.

Best

Shawn

Werner_E
24-Ruby V
(To:sfan)

> Hope this clarify the problem.

Unfortunately not.

Instead of addressing the obviously wrong index number 5 in your post and instead of simply typing in in Mathcad Prime the result you expect given the very example you gave in your last post to show what you are looking for, you again elaborate on what you could and would do in Matlab, introduce new examples which look like they have not much to do with the one you originally gave and introduce something called DOF (what the hell is a DOF?). Why do you think this would clarify anything?

sfan
1-Newbie
(To:Werner_E)

Capture.JPG

Sorry for the confusion. Hope this one might work...

Best

Shawn

Werner_E
24-Ruby V
(To:sfan)

In your original, first post you stated that you want to extract rows/columns from a matrix but now it looks like you try to achieve the opposite - inserting elements from a smaller matrix into a larger one. How would those two different questions fit together?

Anyway:

1) So you will never use the full matrix idx but only one row at a tim, correct?

2) Given k.1 and idx. How would you know that the result should be a 10 x 10 matrix ? Is it determined by the highest index number in idx? Or is the bigger matrix also given from the very beginning. This would mean to write a function with three arguments - k.1, idx and the bigger matrix k.1 should be inserted in according to the first row of idx.

3) Obviously (seen from your ranges i and j) you use default ORIGIN=0 but your idx matrix seems to count beginning from 1. While it would sure be possible to write a routine to cope with that, I find it rather confusing to mix those two ways of indexing the array. I would suggest either to set ORIGIN:=1 or changing the numbers in idx so numbering start with 0 for the first row or column.

sfan
1-Newbie
(To:Werner_E)

Hi, Werner

Yup, they are opposite. But I assume the fundamental method is the same, which is to let Mathcad read/insert a submatrix with respect to a given index vector.

1). Yup, only one row for each time.

2). So it is the latter, 10x10 is predefined from the problem statement (which is the number of Degree of Freedom, DOF). So now I have the big global 10x10 matrix K, and      4 rows in idx (in the problem is 4 elements and each element has 4 Degree of Freedom, which contribute to a 4x4 idx), then I would have to use an iteration to insert      k.1 into K in terms of each row in idx for each iteration.

     If I have for example 4 element but each element have 6 DOFs, then k.1 will become 6x6 and idx will become 4x6.

3). Thank you for your remind. Actually your suggestion coincides with my Professor's today, LOL.. He would prefer Mathcad over Matlab for reading convenience, but      also origin as 1 since that would make the grader's life easier. I often forget about this since most of the programming code starts from 0, but 1 is surely more      readable...

Werner_E
24-Ruby V
(To:sfan)

So far I guess the following should help. You can extract the appropriate row of your idx matrix using Primes row selector.

sfan
1-Newbie
(To:Werner_E)

BTW, in your programming, is the letter O representing number "0"?

Werner_E
24-Ruby V
(To:sfan)

Shawn Fan wrote:

BTW, in your programming, is the letter O representing number "0"?

No, its assigned the value of the system variable ORIGIN (which by default is 0) at the top of the program.

Its simply an abbreviation so I don't have to type ORIGIN every time and in case of my example O has the value 1 because I had set ORIGIN to 1 at the top.

And the usage of ORIGIN in a program assures that it will work OK no matter which value for ORIGIN is selected in a sheet. You can change ORIGIN via the menu (I guess in Prime you simply have the choice between 0 and 1) or you can set it at the top of your sheet to any value you like by typing ORIGIN:=... like its seen in my screenshots.

Personally I prefer ORIGIN to be 0 in my sheets, but when I write a utility function which I might be able to reuse at a later time, I usually try to make it ORIGIN-aware so I won't run into problems if for some reason I decide to set ORIGIN to something different than 0.

If you are sure that you will use the routine only in sheets with ORIGIN set to 1 you may get rid of O and simply use something like "for r in 1 .. rows(small)", etc. which sure is better readable but has to be changed in case ORIGIN is set to 0 one time.

Of course the indices you provide in your index matrix should correspond to the setting of ORIGIN. That means that if you set ORIGIN to 5 (silly choice anyway) your first column or row is index number 5 - you are not allowed to use numbers like 1 or 4 in idx. If ORIGIN is set to 0 (default), your first column is column number 0. Thats the reason I had set ORIGIN:=1 to correspond with the index numbers in the index matrix you provided.

Werner_E
24-Ruby V
(To:sfan)

One additional remark:

If you really want to ADD the small matrix to the values of the larger one instead of just inserting it, you have to change the program:

Top Tags