cumsum method
Performs cumulative sum operations similar to numpy's cumsum but with more flexibility.
Parameters:
continuous
: When true, continues accumulation across axis boundaries (default: false)axis
: The summation axis (null returns flattened list, 0-4 for matrix operations):- null: Flattened list
- 0: Column-wise accumulation
- 1: Row-wise accumulation
- 2: Diagonal (top-left to bottom-right)
- 3: Diagonal (bottom-left to top-right)
- 4: Diagonal (top-right to bottom-left)
Returns:
- List<dynamic> when axis is null
- Matrix when axis is specified
Examples:
var arr = Matrix([
[1, 5, 6],
[4, 7, 2],
[3, 1, 9]
]);
print(arr.cumsum());
// [1, 6, 12, 4, 11, 13, 3, 4, 13]
print(arr.cumsum(continuous: true));
// [1, 6, 12, 16, 23, 25, 28, 29, 38]
print(arr.cumsum(axis: 0));
// ┌ 1 5 6 ┐
// │ 5 12 8 │
// └ 8 13 17 ┘
print(arr.cumsum(continuous: true, axis: 0));
// ┌ 1 13 27 ┐
// │ 5 20 29 │
// └ 8 21 38 ┘
print(arr.cumsum(axis: 1));
// ┌ 1 6 12 ┐
// │ 4 11 13 │
// └ 3 4 13 ┘
print(arr.cumsum(continuous: true, axis: 1));
// ┌ 1 6 12 ┐
// │ 16 23 25 │
// └ 28 29 38 ┘
print(arr.cumsum(axis: 2));
// ┌ 1 5 6 ┐
// │ 4 8 7 │
// └ 3 5 17 ┘
print(arr.cumsum(continuous: true, axis: 2));
// ┌ 9 30 38 ┐
// │ 7 16 32 │
// └ 3 8 25 ┘
print(arr.cumsum(axis: 3));
// ┌ 1 9 16 ┐
// │ 4 10 3 │
// └ 3 1 9 ┘
print(arr.cumsum(continuous: true, axis: 3));
// ┌ 38 37 28 ┐
// │ 32 22 12 │
// └ 15 10 9 ┘
print(arr.cumsum(axis: 4));
// ┌ 1 5 6 ┐
// │ 9 13 2 │
// └ 16 3 9 ┘
print(arr.cumsum(continuous: true, axis: 4));
// ┌ 38 33 18 ┐
// │ 37 25 11 │
// └ 28 12 9 ┘
Implementation
dynamic cumsum({bool continuous = false, int? axis}) {
int rows = _data.length;
int cols = _data[0].length;
List<List<dynamic>> result =
List.generate(rows, (i) => List.filled(cols, 0));
switch (axis) {
case null:
if (continuous) {
// Continuous accumulation across entire matrix
List flat = [];
dynamic cumulative = 0;
for (var row in _data) {
for (var val in row) {
cumulative += val;
flat.add(cumulative);
}
}
return flat;
} else {
// Row-wise accumulation without continuity
List flat = [];
for (var row in _data) {
dynamic rowSum = 0;
for (var val in row) {
rowSum += val;
flat.add(rowSum);
}
}
return flat;
}
case 0: // Column-wise
for (int j = 0; j < cols; j++) {
for (int i = 0; i < rows; i++) {
result[i][j] = _data[i][j];
if (continuous) {
if (j > 0 && i == 0) {
result[i][j] += result[rows - 1][j - 1];
}
if (i > 0) {
result[i][j] += result[i - 1][j];
}
} else {
if (i > 0) {
result[i][j] += result[i - 1][j];
}
}
}
}
break;
case 1: // Row-wise
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result[i][j] = _data[i][j];
if (continuous) {
if (i > 0 && j == 0) {
result[i][j] += result[i - 1][cols - 1];
}
if (j > 0) {
result[i][j] += result[i][j - 1];
}
} else {
if (j > 0) {
result[i][j] += result[i][j - 1];
}
}
}
}
break;
case 2: // Diagonal top-left to bottom-right
if (continuous) {
List<List<int>> coords = [];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
coords.add([i, j]);
}
}
coords.sort((a, b) {
int diffA = a[0] - a[1];
int diffB = b[0] - b[1];
if (diffA != diffB) {
return diffB.compareTo(diffA);
} else {
return a[0].compareTo(b[0]);
}
});
dynamic cumulative = 0;
for (var coord in coords) {
int i = coord[0];
int j = coord[1];
cumulative += _data[i][j];
result[i][j] = cumulative;
}
} else {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result[i][j] = _data[i][j];
if (i > 0 && j > 0) {
result[i][j] += result[i - 1][j - 1];
}
}
}
}
case 3: // Diagonal bottom-left to top-right
if (continuous) {
List<List<int>> coords = [];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
coords.add([i, j]);
}
}
coords.sort((a, b) {
int sumA = a[0] + a[1];
int sumB = b[0] + b[1];
if (sumA != sumB) {
return sumB.compareTo(sumA);
} else {
return b[0].compareTo(a[0]);
}
});
dynamic cumulative = 0;
for (var coord in coords) {
int i = coord[0];
int j = coord[1];
cumulative += _data[i][j];
result[i][j] = cumulative;
}
} else {
for (int j = 0; j < cols; j++) {
for (int i = rows - 1; i >= 0; i--) {
result[i][j] = _data[i][j];
if (i < rows - 1 && j > 0) {
result[i][j] += result[i + 1][j - 1];
}
}
}
}
break;
case 4: // Diagonal top-right to bottom-left
if (continuous) {
List<List<int>> coords = [];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
coords.add([i, j]);
}
}
coords.sort((a, b) {
int sumA = a[0] + a[1];
int sumB = b[0] + b[1];
if (sumA != sumB) {
return sumB.compareTo(sumA);
} else {
return b[1].compareTo(a[1]);
}
});
dynamic cumulative = 0;
for (var coord in coords) {
int i = coord[0];
int j = coord[1];
cumulative += _data[i][j];
result[i][j] = cumulative;
}
} else {
for (int j = cols - 1; j >= 0; j--) {
for (int i = 0; i < rows; i++) {
result[i][j] = _data[i][j];
if (i > 0 && j < cols - 1) {
result[i][j] += result[i - 1][j + 1];
}
}
}
}
break;
default:
throw ArgumentError('Invalid axis value');
}
return Matrix(result);
}