4

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.

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
immaan
  • 77
  • 7

3 Answers3

2
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

enter image description here

eldo
  • 67,911
  • 5
  • 60
  • 168
  • 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 – immaan Dec 08 '15 at 14:44
1

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}}*)
Hubble07
  • 3,614
  • 13
  • 23
1

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}}

garej
  • 4,865
  • 2
  • 19
  • 42
  • @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. – garej Dec 09 '15 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. – immaan Dec 09 '15 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. – garej Dec 10 '15 at 08: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. – immaan Dec 10 '15 at 08: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. – garej Dec 10 '15 at 10:28
  • True, and this is all in the 'Module' help by mathematica. The only problem I get, is when I want to have this in multi dimensional tables, like Matrixes as stated in the question. – immaan Dec 10 '15 at 17:20