I have two matrices a = m x 5 and b =m x 5 (m is large, say 1,000) which are already sorted as below:

How to generate a new matrix c = m x 5 which consists:

Column 1: exact replica of Column 1 of matrix a.
Column 2: Depends on non-zero elements of b as shown
so that it is adjusted by it's left hand side row of a - b + present row.
Zeros are not evaluated.

(example: 3.7107 - 2.96856 + 23.2988 = 24.0409 )

Columns 3 4 and 5, not sure yet so maybe start off with a SparseArray of m x 5? But most likely to be an extension of Column 2. i.e. Column 3,4 and 5 will be also adjusted once I have worked out how they need to adjusted by.

3 Answers
3

Let me show you a way which hopefully helps you to solve such things alone next time. If you cannot implement your overall task, have you asked yourself, whether you can solve a sub-problem of your task? For instance, if you have one row of a and one row of b would you be able to combine this into the resulting row?

Basically, you are only interested in the first elements of each row. A combine function could look like the following

The first entry in the result is a copy of of the first column of a and the second entry is the linear combination you described. I set the other ones to zero.

Now you want to apply this function to each a-b-row pair. For this you have to use a function which takes the appropriate rows from each matrix (first of a and b, second of a and b, ...) and applies combine. Exactly this is what MapThread is for

@NasserM.Abbasi, for this there are million ways but first comes, that the OP learns something and then, after a long while we maybe take a look at the speed of the implementation. Btw, 1000 rows are not critical.
–
halirutanDec 30 '12 at 3:06

Hi @halirutan this answer works but as Mr Wizard mentioned, does not treat my second column of zero elements well, it still does the a1 - b1 + b2 for the second column of elements even though that element is zero. As mentioned zero should simply be left as zero. if the second column of non-zero elements for matrix c must still be the same number of b non-zero elements.
–
sebastian c.Dec 31 '12 at 3:03

1

@sebastianc. That's why I wrote "combinecould look like" and "hopefully helps you to solve such things alone next time". Question: Can you change combine so that it fits your needs when there is a zero in the second column? The goal is to help you, not to do the homework.
–
halirutanDec 31 '12 at 3:24

The matrix the way you specified it so far is an $m \times 2$ matrix with entries:

Transpose@{a[[All, 1]], a[[All, 1]] - b[[All,1]] + b[[All, 2]]}

To add the other columns, just extend the list above. This way of specifying whole columns by All in the first argument of Part ([[...]]) is the simplest thing I can think of given the fact that your manipulations seem to be formally the same for each row, i.e., they are just linear combinations of columns.

Similarly to my answer there I advise that you use numeric methods where possible any time you are working with large matrices or where performance is important. halirutan shows a pattern-based method that is easy to read and understand (which earned it my vote) but it is not likely to scale well. (Also, his answer as written does not treat zeros the way I think you want based on the earlier answer.)

Here is an example using Part and Unitize. First create samples a and b:

If you are going to make frequent column-based changes to your data you would do well to Transpose it so that columns can be accessed without All. You can always use Transpose again to return the data to its original form.

Thanks @Mr Wizard but the logic is above, slightly different logic you have here. Take for example third row, second column it would be 7.89-8.34+4.71=4.26 and not 11.51 as shown, with a and b matrices ascending order left to right.
–
sebastian c.Jan 2 '13 at 14:05

Mathematica is a registered trademark of Wolfram Research, Inc. While the mark is used herein with the limited permission of Wolfram Research, Stack Exchange and this site disclaim all affiliation therewith.