12
$\begingroup$

For a matrix

{{1,a},{2,b},{3,c},{4,d}},

how do I use the command Accumulate to get the matrix

{{1,a},{2,a+b},{3,a+b+c},{4, a+b+c+d}}?

One can break apart the matrix

list1={1,2,3,4} and list2 = {a,b,c,d}

and let

list3=Accumulate[list2]

and then let

list4=Transpose[{list1,list3}] 

This gives what I want.

Is there a more direct way?

$\endgroup$
1
  • 3
    $\begingroup$ The steps can be combined Transpose[{list[[All, 1]], Accumulate@list[[All, 2]]}]. $\endgroup$ Dec 23, 2022 at 16:45

4 Answers 4

11
$\begingroup$

Using SubsetMap:

amat = {{1, a}, {2, b}, {3, c}, {4, d}}
SubsetMap[Accumulate, amat, {All, 2}]

Using FoldList:

FoldList[{First@#2, Last@#1 + Last@#2} &, amat]

Result:

{{1, a}, {2, a + b}, {3, a + b + c}, {4, a + b + c + d}}


Using Construct and MapThread:

To apply different functions to columns, let's start with with a 3-column example matrix called bmat.

bmat = {{1, a, w}, {2, b, x}, {3, c, y}, {4, d, z}}
funcs = {Identity, Accumulate, #^2 &};
Transpose@MapThread[Construct, {funcs, Transpose@bmat}] // TableForm

{{1, a, w^2}, {2, a + b, x^2}, {3, a + b + c, y^2}, {4, a + b + c + d, z^2}}

$$\left( \begin{array}{ccc} 1 & a & w^2 \\ 2 & a+b & x^2 \\ 3 & a+b+c & y^2 \\ 4 & a+b+c+d & z^2 \\ \end{array} \right)$$

$\endgroup$
2
  • $\begingroup$ Why doesn't MapAt[Accumulate, amat, {All, 2}] work? I tried this. $\endgroup$
    – complex
    Dec 23, 2022 at 17:26
  • $\begingroup$ It applies to individual locations. MapAt[f, amat, {All, 2}]. $\endgroup$
    – Syed
    Dec 23, 2022 at 17:34
10
$\begingroup$

Another possibility:

list = {{1,a},{2,b},{3,c},{4,d}};

list[[All,2]] = Accumulate[list[[All,2]]];

Then list has the desired output:

list

{{1, a}, {2, a + b}, {3, a + b + c}, {4, a + b + c + d}}

$\endgroup$
1
  • $\begingroup$ Why the downvote? And (once again) no explanatory comment. $\endgroup$
    – user1066
    Dec 25, 2022 at 9:48
2
$\begingroup$

Using MapAt:

amat = {{1, a}, {2, b}, {3, c}, {4, d}}
Transpose@MapAt[Accumulate, Transpose@amat, {2}]
(*{{1, a}, {2, a + b}, {3, a + b + c}, {4, a + b + c + d}}*)

Or using Table and Partition:

Table[{amat[[i, 1]], Total@(First@Partition[amat[[All, 2]], amat[[i, 1]]])}, {i, 1, Length[amat]}]
(*{{1, a}, {2, a + b}, {3, a + b + c}, {4, a + b + c + d}}*)
$\endgroup$
2
$\begingroup$

Some other methods

Query

Module[{i=0},Query[All, {2 -> (i+=#&)}]]@mat

(* {{1, a}, {2, a + b}, {3, a + b + c}, {4, a + b + c + d}} *)

The 'compiled form' of Query here uses MapAt 'under the hood'

Query[All, {2 -> (i+=#&)}]//Normal

MapAt[i += #1 & , {All, 2}]

MapAt

Module[{i=0},MapAt[i+=#&,{All,2}]]@mat

(* {{1, a}, {2, a + b}, {3, a + b + c}, {4, a + b + c + d}} *)

ApplyTo and Accumulate

Using a modification of the neat method posted below by Carl Woll (without in-place modification):

Module[{temp=#},temp[[All,2]]//=Accumulate;temp]&@mat

{{1, a}, {2, a + b}, {3, a + b + c}, {4, a + b + c + d}}

Matrix

mat={{1,a},{2,b},{3,c},{4,d}};
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.