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

## How to extract non-consecutive submatrix in a easier way  1-Newbie

## How to extract non-consecutive submatrix in a easier way

Hi, everyone,

If I have a 100 by 100 matrix and I want to extract its 10 to 20, 40 to 50 and 70 to 80 rows and columns,

Is there a easier way rather than submatrix the rows first and then the columns and use stack or augment to assemble the submatrice?

Such as define a index of the rows and columns I want to extract and then extract the index from the matrix in Matlab?

E.g, index= [10:20 40:50 70:80]

K_BC=K(index, index)

Best

Shawn

1 ACCEPTED SOLUTION

Accepted Solutions  23-Emerald II
(To:sfan)
 Shawn Fan wrote: Hi, everyone, If I have a 100 by 100 matrix and I want to extract its 10 to 20, 40 to 50 and 70 to 80 rows and columns, Is there a easier way rather than submatrix the rows first and then the columns and use stack or augment to assemble the submatrice? Such as define a index of the rows and columns I want to extract and then extract the index from the matrix in Matlab? E.g, index= [10:20 40:50 70:80] K_BC=K(index, index)

I'm not sure there's an easy way in Prime (or in Mathcad 15). Improvements to array indexing to allow such things have been on my (submitted) wishlist for a long time. To my mind, the "natural" Mathcad way to do this would be by using a range variable to store ranges of the form "(10..20),(40..50),(70..80)". Whilst Mathcad 15 won't let you assign such a range to a range variable, it will let you enter it as the list of elements in a for loop, so you could just write "for r e (10..20),(40..50),(70..80) <code to extract row r and build the result matrix>", not as neat as Matlab, but it will work. The downside is that you can't pass such a range as an argument to a function or assign it to a range variable.

The even bigger downside to Prime is that you can't even enter such expressions or enter standard ranges as arguments to functions! This prevents several of my Mathcad 15 worksheets from working in Prime.

However, all is not total gloom as it's possible to write a function that will interpret a string like "10:20 40:50 70:80" and explicitly expand the implied range. The Big Black Cloud that accompanies this thin silver lining is that I've got the trial version of Prime 3.1 and you can't read it. I could write a Mathcad 15 version, which you could convert (provided you've got Mathcad 15), but my Prime version takes advantage of Prime's matrix row extraction operator to simplify things and Mathcad 15 only has the equivalent column operator. Unfortunately, I can't create the Mathcad 15 version at the moment.

Stuart

Here's an example of a function pickrows that will interpret a string as a range and pick out the desired rows. R is the matrix of interest. slist is a range that uses "," to separate ranges (as per normal Mathcad usage) and slist2 uses spaces to separate the ranges; both use the colon as per Matlab normal usage).

It makes use of my function str2arr that converts a string into an array, using a delimiter string "cr" where c is the column delimiter character and r is the row delimiter character. Functions needed to support pickrows ...  5 REPLIES 5  23-Emerald II
(To:sfan)
 Shawn Fan wrote: Hi, everyone, If I have a 100 by 100 matrix and I want to extract its 10 to 20, 40 to 50 and 70 to 80 rows and columns, Is there a easier way rather than submatrix the rows first and then the columns and use stack or augment to assemble the submatrice? Such as define a index of the rows and columns I want to extract and then extract the index from the matrix in Matlab? E.g, index= [10:20 40:50 70:80] K_BC=K(index, index)

I'm not sure there's an easy way in Prime (or in Mathcad 15). Improvements to array indexing to allow such things have been on my (submitted) wishlist for a long time. To my mind, the "natural" Mathcad way to do this would be by using a range variable to store ranges of the form "(10..20),(40..50),(70..80)". Whilst Mathcad 15 won't let you assign such a range to a range variable, it will let you enter it as the list of elements in a for loop, so you could just write "for r e (10..20),(40..50),(70..80) <code to extract row r and build the result matrix>", not as neat as Matlab, but it will work. The downside is that you can't pass such a range as an argument to a function or assign it to a range variable.

The even bigger downside to Prime is that you can't even enter such expressions or enter standard ranges as arguments to functions! This prevents several of my Mathcad 15 worksheets from working in Prime.

However, all is not total gloom as it's possible to write a function that will interpret a string like "10:20 40:50 70:80" and explicitly expand the implied range. The Big Black Cloud that accompanies this thin silver lining is that I've got the trial version of Prime 3.1 and you can't read it. I could write a Mathcad 15 version, which you could convert (provided you've got Mathcad 15), but my Prime version takes advantage of Prime's matrix row extraction operator to simplify things and Mathcad 15 only has the equivalent column operator. Unfortunately, I can't create the Mathcad 15 version at the moment.

Stuart

Here's an example of a function pickrows that will interpret a string as a range and pick out the desired rows. R is the matrix of interest. slist is a range that uses "," to separate ranges (as per normal Mathcad usage) and slist2 uses spaces to separate the ranges; both use the colon as per Matlab normal usage).

It makes use of my function str2arr that converts a string into an array, using a delimiter string "cr" where c is the column delimiter character and r is the row delimiter character. Functions needed to support pickrows ...    23-Emerald I
(To:sfan)

What am I missing? Isn't this what "submatrix" does?  23-Emerald II
(To:Fred_Kohlhepp)
 Fred Kohlhepp wrote: What am I missing? Isn't this what "submatrix" does?

Well, yes and no. Submatrix will do the job in part, but then you've got the hassle of stacking the various submatrices back together again ... which the OP wanted to avoid if possible.

Entering the list of rows as a string seemed to be the easiest way to express the list, but a nested array is also a possibility - I've used a row vector format for the simple function below. The new function doesn't require any extra support functions, but, whilst the new matrix entry scheme makes it easier than M15 to enter an array, it's still nowhere near as simple as typing a string. Of course, what's really needed is an extended range notation that would allow the user to directly create the range (1..3),0,(5..7) as used in the example below or (10..20),(40..50),(70..80) as in the OP's original post.

I've been having a quick play with the latest trial version of Prime and, whilst there are indeed many things that are frustratingly absent (like many of the M15 features I use and something called performance), there are a few things that I quite like, the row operator being one of them and the ability to quickly enter new rows / columns into an array ... I've even got the hang of some of the keyboard shortcuts, as the ribbon is another of those frustrations ...

Stuart   1-Newbie
(To:Fred_Kohlhepp)

Hi, Fred,

It is just not possible to program inside submatrix function, like submatrix(K, i,i+10,j,j+10)  23-Emerald II
(To:sfan)
 Shawn Fan wrote: Hi, Fred, It is just not possible to program inside submatrix function, like submatrix(K, i,i+10,j,j+10)

There's something about things not being possible that's like a red rag to a bull for me and I just can't help trying to prove it is possible! You're right that it isn't possible to directly create ranges with gaps in them, but it's possible to use range variable to index into a vector of such values, and this technique might be of some use to somebody. And there's no reason why we can't cheat a little and define our own SubMatrix function to allow us to give arbitrary row and column lists Stuart 