# How can I make custom accumulated sequences like the following?

First of all, I don't really know how to formulate the question, so if you understand my question and know a better way to phrase it, please revise.

I have the following Matrixes:

a[n_, m_] := Table[n + m - i - j, {i, 1, n}, {j, 1, m}]
b[n_, m_] := Round[Table[(n*m/2)*(1 + 2 j/m), {j, 1, m}]]


(these are just chosen to test the sequence). Where a[n,m] is a nxm Matrix, and b[n,m] a vector of length m.

I want to make a sequence that accumulates a[n,m], but, when it becomes higher than b[n,m] at a certain m, it has to take the respective value of b[n,m] and continue the accumulations (or another exception).

I tried a couple of ways like with FoldList and MapThread or RecurrenceTable. But I just didn't get there. I think there is a simple way which I just didn't think of.

Finally I just did it by hand (and called it c[n,m]) with a[3,8] and b[3,8]

a[3,8] =
{{9, 8, 7, 6, 5, 4, 3, 2},
{8, 7, 6, 5, 4, 3, 2, 1},
{7, 6, 5, 4, 3, 2, 1, 0}}

b[3,8] = {15, 18, 21, 24, 27, 30, 33, 36}


c[3,8] = {{9, 17, 21, 24, 27, 30, 33, 35}, {8, 15, 21, 24, 27, 30, 32, 33}, {7, 13, 18, 22, 25, 27, 28, 28}}

I hope you can help me out.

Initial setting:

Clear[a, b, A, B]
a[3, 8] = {{9, 8, 7, 6, 5, 4, 3, 2}, {8, 7, 6, 5, 4, 3, 2, 1}, {7, 6,
5, 4, 3, 2, 1, 0}};
b[3, 8] = {15, 18, 21, 24, 27, 30, 33, 36};


Prepare data:

B = Prepend[b[3, 8], 0]; A = Prepend[#, 0] & /@ a[3, 8];


Function:

f[A_, B_] :=
Module[{i = 2, a = A, b = B},
While[i++ < Length@b,
a[[i]] = Min[b[[i]], Total@a[[i - 1 ;; i]]]];
Rest@a
]


Application:

f[#, B] & /@ A


Result:

{{9, 17, 21, 24, 27, 30, 33, 35}, {8, 15, 21, 24, 27, 30, 32, 33}, {7, 13, 18, 22, 25, 27, 28, 28}}

• @immaan, thank you for accepting. Note that uppercase for variables is a bit agains convention in MMA, but I've used it for better transparency of the code. Commented Dec 9, 2015 at 11:04
• I very well see! but how did you get to this solution... it is way shorter then the others and more understandable. But as I continue, I am wondering how to do it in more arbitrary ways. Commented Dec 9, 2015 at 21:11
• @immaan, I'm not sure what do you mean by 'arbitrary'. A for the task, it seemed to me a good example where traditional 'procedural' style is ok. in general, try to compare flat simple lists at first. Matrixes (lists of lists) just add some complexity. Commented Dec 10, 2015 at 8:02
• I mean how to create a more sequences like this in more general way. (timed sequences) like 'f[t] == g[t,f[t-1]]'. But I think that will just be my next question to ask here in public. So if you don't know how to answer it, please tell me how these sequences are called, so I can formulate my question right. Commented Dec 10, 2015 at 8:58
• @immaan, I would start from this question and related links. I guess your concern is recurrence sequences. There are a lot of syntactic sugar in MMA for that stuff. Commented Dec 10, 2015 at 10:28
a[n_, m_] := Table[n + m - i - j, {i, 1, n}, {j, 1, m}];
b[n_, m_] := Round[Table[(n*m/2)*(1 + 2 j/m), {j, 1, m}]];

fun[li_, rp_] :=
Module[{p = First@FirstPosition[li - rp, _?Positive]},
If[p === "NotFound", li, Join[li[[;; p - 1]], rp[[p ;;]]]]]

fun[#, b[3, 8]] & /@ Accumulate /@ a[3, 8] // MatrixForm


• First of all, thank you for your reaction! It looks pretty complicated and is on the right path. But, there is a point where your function did not work. For the first row its the last number, and for the second row the last two numbers. There you can see that it did not go back to the state where it had to check for the Minimum again. Like in my output, First row: 33+2<36, Second row: 30+2<32, 30+2+1<35 Commented Dec 8, 2015 at 14:44

The function below in association with NestList can be used for two list of equal length.

myAccumulate[{lista_, listb_}] :=
Module[{tot, l1, l2},
l1 = lista; l2 = listb;
(*collect the minimum value*)
ans = Flatten[Join[{ans, Min[l1[[1]], l2[[1]]]}]];

Which[Length[l1] == 1 && Length[l2] == 1, {l1, l2} = {{}, {}}, True,
l1 = Drop[l1, {1}];
tot = Total[{Last[ans], l1[[1]]}];
l1 = Drop[l1, {1}];
PrependTo[l1, tot];
l2 = Drop[l2, {1}]];
{l1, l2}
]


For example with the following two list we get

list1 = {9, 8, 7, 6, 5, 4, 3, 2};
list2 = {15, 18, 21, 24, 27, 30, 33, 36};
ans = {};
NestList[myAccumulate, {list1, list2}, 8];
ans

(*{9, 17, 21, 24, 27, 30, 33, 35}*)


The list ans stores the minimum value for each iteration. For your list you can use it as follows:

Table[
ans = {};
NestList[myAccumulate, {a[3, 8][[i]], b[3, 8]}, Length[b[3, 8]]];
ans, {i, 3}]

(*{{9, 17, 21, 24, 27, 30, 33, 35}, {8, 15, 21, 24, 27, 30, 32, 33}, {7,
13, 18, 22, 25, 27, 28, 28}}*)