Skip to content

Commit 7abd239

Browse files
caos321xzero
and
xzero
authored
Add MatrixUtil for matrix operations (TheAlgorithms#2798)
Co-authored-by: xzero <[email protected]>
1 parent 5b261e9 commit 7abd239

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

Maths/MatrixUtil.java

+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
package Maths;
2+
3+
import java.math.BigDecimal;
4+
import java.util.Arrays;
5+
import java.util.Objects;
6+
import java.util.Optional;
7+
import java.util.function.BiFunction;
8+
import java.util.stream.IntStream;
9+
10+
/**
11+
* @author: caos321
12+
* @date: 31 October 2021 (Sunday)
13+
*/
14+
public class MatrixUtil {
15+
16+
public static boolean isValid(final BigDecimal[][] matrix) {
17+
return matrix != null && matrix.length > 0 && matrix[0].length > 0;
18+
}
19+
20+
public static boolean hasEqualSizes(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) {
21+
return isValid(matrix1) && isValid(matrix2)
22+
&& matrix1.length == matrix2.length
23+
&& matrix1[0].length == matrix2[0].length;
24+
}
25+
26+
public static boolean canMultiply(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) {
27+
return isValid(matrix1) && isValid(matrix2)
28+
&& matrix1[0].length == matrix2.length;
29+
}
30+
31+
public static Optional<BigDecimal[][]> operate(final BigDecimal[][] matrix1,
32+
final BigDecimal[][] matrix2,
33+
final BiFunction<BigDecimal, BigDecimal, BigDecimal> operation) {
34+
if (!hasEqualSizes(matrix1, matrix2)) {
35+
return Optional.empty();
36+
}
37+
38+
final int rowSize = matrix1.length;
39+
final int columnSize = matrix1[0].length;
40+
41+
final BigDecimal[][] result = new BigDecimal[rowSize][columnSize];
42+
43+
IntStream.range(0, rowSize).forEach(rowIndex ->
44+
IntStream.range(0, columnSize).forEach(columnIndex -> {
45+
final BigDecimal value1 = matrix1[rowIndex][columnIndex];
46+
final BigDecimal value2 = matrix2[rowIndex][columnIndex];
47+
48+
result[rowIndex][columnIndex] = operation.apply(value1, value2);
49+
}));
50+
51+
return Optional.of(result);
52+
}
53+
54+
public static Optional<BigDecimal[][]> add(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) {
55+
return operate(matrix1, matrix2, BigDecimal::add);
56+
}
57+
58+
public static Optional<BigDecimal[][]> subtract(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) {
59+
return operate(matrix1, matrix2, BigDecimal::subtract);
60+
}
61+
62+
public static Optional<BigDecimal[][]> multiply(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) {
63+
if (!canMultiply(matrix1, matrix2)) {
64+
return Optional.empty();
65+
}
66+
67+
final int size = matrix1[0].length;
68+
69+
final int matrix1RowSize = matrix1.length;
70+
final int matrix2ColumnSize = matrix2[0].length;
71+
72+
final BigDecimal[][] result = new BigDecimal[matrix1RowSize][matrix2ColumnSize];
73+
74+
IntStream.range(0, matrix1RowSize).forEach(rowIndex ->
75+
IntStream.range(0, matrix2ColumnSize).forEach(columnIndex ->
76+
result[rowIndex][columnIndex] = IntStream.range(0, size).mapToObj(index -> {
77+
final BigDecimal value1 = matrix1[rowIndex][index];
78+
final BigDecimal value2 = matrix2[index][columnIndex];
79+
80+
return value1.multiply(value2);
81+
})
82+
.reduce(BigDecimal.ZERO, BigDecimal::add)
83+
)
84+
);
85+
86+
return Optional.of(result);
87+
}
88+
89+
public static void assertThat(final BigDecimal[][] actual, final BigDecimal[][] expected) {
90+
if (!Objects.deepEquals(actual, expected)) {
91+
throw new AssertionError(String.format(
92+
"expected=%s but was actual=%s",
93+
Arrays.deepToString(expected),
94+
Arrays.deepToString(actual)
95+
));
96+
}
97+
}
98+
99+
public static void main(final String[] args) {
100+
{
101+
final BigDecimal[][] matrix1 = {
102+
{new BigDecimal(3), new BigDecimal(2)},
103+
{new BigDecimal(0), new BigDecimal(1)},
104+
};
105+
106+
final BigDecimal[][] matrix2 = {
107+
{new BigDecimal(1), new BigDecimal(3)},
108+
{new BigDecimal(2), new BigDecimal(0)},
109+
};
110+
111+
final BigDecimal[][] actual = add(matrix1, matrix2)
112+
.orElseThrow(() -> new AssertionError("Could not compute matrix!"));
113+
114+
final BigDecimal[][] expected = {
115+
{new BigDecimal(4), new BigDecimal(5)},
116+
{new BigDecimal(2), new BigDecimal(1)}
117+
};
118+
119+
assertThat(actual, expected);
120+
}
121+
122+
{
123+
final BigDecimal[][] matrix1 = {
124+
{new BigDecimal(1), new BigDecimal(4)},
125+
{new BigDecimal(5), new BigDecimal(6)},
126+
};
127+
128+
final BigDecimal[][] matrix2 = {
129+
{new BigDecimal(2), new BigDecimal(0)},
130+
{new BigDecimal(-2), new BigDecimal(-3)},
131+
};
132+
133+
final BigDecimal[][] actual = subtract(matrix1, matrix2)
134+
.orElseThrow(() -> new AssertionError("Could not compute matrix!"));
135+
136+
final BigDecimal[][] expected = {
137+
{new BigDecimal(-1), new BigDecimal(4)},
138+
{new BigDecimal(7), new BigDecimal(9)}
139+
};
140+
141+
assertThat(actual, expected);
142+
}
143+
144+
{
145+
final BigDecimal[][] matrix1 = {
146+
{new BigDecimal(1), new BigDecimal(2), new BigDecimal(3)},
147+
{new BigDecimal(4), new BigDecimal(5), new BigDecimal(6)},
148+
{new BigDecimal(7), new BigDecimal(8), new BigDecimal(9)}
149+
};
150+
151+
final BigDecimal[][] matrix2 = {
152+
{new BigDecimal(1), new BigDecimal(2)},
153+
{new BigDecimal(3), new BigDecimal(4)},
154+
{new BigDecimal(5), new BigDecimal(6)}
155+
};
156+
157+
final BigDecimal[][] actual = multiply(matrix1, matrix2)
158+
.orElseThrow(() -> new AssertionError("Could not compute matrix!"));
159+
160+
final BigDecimal[][] expected = {
161+
{new BigDecimal(22), new BigDecimal(28)},
162+
{new BigDecimal(49), new BigDecimal(64)},
163+
{new BigDecimal(76), new BigDecimal(100)}
164+
};
165+
166+
assertThat(actual, expected);
167+
}
168+
}
169+
}

0 commit comments

Comments
 (0)