Community Tip - Did you know you can set a signature that will be added to all your posts? Set it here! X
In Matlab, when I plan to extract a submatrix from a large matrix in the following situation:
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
Solved! Go to Solution.
So far I guess the following should help. You can extract the appropriate row of your idx matrix using Primes row selector.
That is not supported as a built in function. You can program it though.
Luc
This discussion might help...
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.
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?
Hi, Werner,
Sorry I truncate the original problem that results in some confusion.
The original one is this:
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
> 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?
Sorry for the confusion. Hope this one might work...
Best
Shawn
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.
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...
So far I guess the following should help. You can extract the appropriate row of your idx matrix using Primes row selector.
BTW, in your programming, is the letter O representing number "0"?
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.
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: