Skip to content

Commit e1d603f

Browse files
author
R. Kaleta
committed
Expose all coefficients in equation
1 parent 984f76e commit e1d603f

4 files changed

Lines changed: 67 additions & 64 deletions

File tree

src/main/java/algolib/maths/Equation.java

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.text.DecimalFormatSymbols;
55
import java.util.Arrays;
66
import java.util.Locale;
7-
import java.util.Objects;
87
import java.util.stream.Collectors;
98
import java.util.stream.IntStream;
109

@@ -20,6 +19,11 @@ private Equation(double[] coefficients, double freeTerm)
2019
this.freeTerm = freeTerm;
2120
}
2221

22+
public double[] getCoefficients()
23+
{
24+
return coefficients;
25+
}
26+
2327
public double getFreeTerm()
2428
{
2529
return freeTerm;
@@ -30,25 +34,6 @@ public static Equation of(double[] coefficients, double free)
3034
return new Equation(coefficients, free);
3135
}
3236

33-
@Override
34-
public boolean equals(Object obj)
35-
{
36-
if(this == obj)
37-
return true;
38-
39-
if(!(obj instanceof Equation other))
40-
return false;
41-
42-
return Double.compare(other.freeTerm, freeTerm) == 0 && Arrays.equals(coefficients,
43-
other.coefficients);
44-
}
45-
46-
@Override
47-
public int hashCode()
48-
{
49-
return Objects.hash(freeTerm, Arrays.hashCode(coefficients));
50-
}
51-
5237
@Override
5338
public String toString()
5439
{
@@ -69,16 +54,6 @@ public int size()
6954
return coefficients.length;
7055
}
7156

72-
/**
73-
* Gets the coefficient by the variable at given index.
74-
* @param i the index of variable
75-
* @return the coefficient specified by the index
76-
*/
77-
public double getCoefficient(int i)
78-
{
79-
return coefficients[i];
80-
}
81-
8257
/**
8358
* Negates this equation.
8459
* @return the equation with all coefficients negated

src/main/java/algolib/maths/EquationSystem.java

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package algolib.maths;
22

33
import java.util.Arrays;
4+
import java.util.stream.Collectors;
45

56
/** Structure of system of linear equations. */
67
public final class EquationSystem
@@ -38,6 +39,14 @@ public int hashCode()
3839
return Arrays.hashCode(equations);
3940
}
4041

42+
@Override
43+
public String toString()
44+
{
45+
return "{ %s }".formatted(Arrays.stream(equations)
46+
.map(Equation::toString)
47+
.collect(Collectors.joining(" ; ")));
48+
}
49+
4150
/**
4251
* Gets the number of equations in this system.
4352
* @return the number of equations
@@ -68,29 +77,29 @@ public double[] solve()
6877
{
6978
gaussianReduce();
7079

71-
if(equations[equations.length - 1].getCoefficient(equations.length - 1) == 0
72-
&& equations[equations.length - 1].getFreeTerm() == 0)
80+
int lastIndex = equations.length - 1;
81+
82+
if(equations[lastIndex].getCoefficients()[lastIndex] == 0
83+
&& equations[lastIndex].getFreeTerm() == 0)
7384
throw new InfiniteSolutionsException();
7485

75-
if(equations[equations.length - 1].getCoefficient(equations.length - 1) == 0
76-
&& equations[equations.length - 1].getFreeTerm() != 0)
86+
if(equations[lastIndex].getCoefficients()[lastIndex] == 0
87+
&& equations[lastIndex].getFreeTerm() != 0)
7788
throw new NoSolutionException();
7889

7990
double[] solution = new double[equations.length];
8091

81-
solution[equations.length - 1] =
82-
equations[equations.length - 1].getFreeTerm() / equations[equations.length
83-
- 1].getCoefficient(
84-
equations.length - 1);
92+
solution[lastIndex] = equations[lastIndex].getFreeTerm()
93+
/ equations[lastIndex].getCoefficients()[lastIndex];
8594

8695
for(int i = equations.length - 2; i >= 0; --i)
8796
{
8897
double value = equations[i].getFreeTerm();
8998

90-
for(int j = equations.length - 1; j > i; --j)
91-
value -= equations[i].getCoefficient(j) * solution[j];
99+
for(int j = lastIndex; j > i; --j)
100+
value -= equations[i].getCoefficients()[j] * solution[j];
92101

93-
solution[i] = value / equations[i].getCoefficient(i);
102+
solution[i] = value / equations[i].getCoefficients()[i];
94103
}
95104

96105
return solution;
@@ -101,24 +110,16 @@ public void gaussianReduce()
101110
{
102111
for(int i = 0; i < equations.length - 1; ++i)
103112
{
104-
int indexMin = i;
105-
106-
for(int j = i + 1; j < equations.length; ++j)
107-
{
108-
double minCoef = equations[indexMin].getCoefficient(i);
109-
double actCoef = equations[j].getCoefficient(i);
110-
111-
if(actCoef != 0 && (minCoef == 0 || Math.abs(actCoef) < Math.abs(minCoef)))
112-
indexMin = j;
113-
}
113+
int indexMin = getMinimalCoefficientIndex(i);
114114

115-
if(equations[indexMin].getCoefficient(i) != 0)
115+
if(equations[indexMin].getCoefficients()[i] != 0)
116116
{
117117
swap(indexMin, i);
118118

119119
for(int j = i + 1; j < equations.length; ++j)
120120
{
121-
double param = equations[j].getCoefficient(i) / equations[i].getCoefficient(i);
121+
double param =
122+
equations[j].getCoefficients()[i] / equations[i].getCoefficients()[i];
122123

123124
if(param != 0)
124125
equations[j] = equations[j].add(equations[i].multiply(-param));
@@ -149,4 +150,22 @@ public boolean hasSolution(double[] solution)
149150
{
150151
return Arrays.stream(equations).allMatch(eq -> eq.hasSolution(solution));
151152
}
153+
154+
private int getMinimalCoefficientIndex(int startingIndex)
155+
{
156+
int indexMin = startingIndex;
157+
158+
for(int i = startingIndex + 1; i < equations.length; ++i)
159+
{
160+
double minCoefficient = equations[indexMin].getCoefficients()[startingIndex];
161+
double currentCoefficient = equations[i].getCoefficients()[startingIndex];
162+
163+
if(currentCoefficient != 0 && (minCoefficient == 0
164+
|| Math.abs(currentCoefficient) < Math.abs(
165+
minCoefficient)))
166+
indexMin = i;
167+
}
168+
169+
return indexMin;
170+
}
152171
}

src/test/java/algolib/maths/EquationSystemTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,21 @@
66
// Tests: Structure of linear equations system.
77
public class EquationSystemTest
88
{
9+
@Test
10+
public void toString_ThenStringRepresentation()
11+
{
12+
// given
13+
var testObject = EquationSystem.of(Equation.of(new double[]{2.0, 3.0, -2.0}, 15),
14+
Equation.of(new double[]{7.0, -1.0, 0.0}, 4),
15+
Equation.of(new double[]{-1.0, 6.0, 4.0}, 9));
16+
// when
17+
String result = testObject.toString();
18+
// then
19+
Assertions.assertThat(result)
20+
.isEqualTo("{ 2 x_0 + 3 x_1 + -2 x_2 = 15 ; 7 x_0 + -1 x_1 = 4 ; "
21+
+ "-1 x_0 + 6 x_1 + 4 x_2 = 9 }");
22+
}
23+
924
@Test
1025
public void solve_WhenSingleSolution_ThenSolution()
1126
{

src/test/java/algolib/maths/EquationTest.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package algolib.maths;
22

3-
import java.util.stream.IntStream;
43
import org.assertj.core.api.Assertions;
54
import org.junit.jupiter.api.AfterEach;
65
import org.junit.jupiter.api.BeforeEach;
@@ -29,7 +28,7 @@ public void negate_ThenNegated()
2928
// when
3029
Equation result = testObject.negate();
3130
// then
32-
Assertions.assertThat(coefficients(result))
31+
Assertions.assertThat(result.getCoefficients())
3332
.usingComparatorWithPrecision(0.0)
3433
.containsExactly(-2, -3, 0, 2.5);
3534
Assertions.assertThat(result.getFreeTerm()).isEqualTo(-15);
@@ -41,7 +40,7 @@ public void add_ThenAddingEquations()
4140
// when
4241
Equation result = testObject.add(Equation.of(new double[]{1, -1, 4, 10}, 5));
4342
// then
44-
Assertions.assertThat(coefficients(result))
43+
Assertions.assertThat(result.getCoefficients())
4544
.usingComparatorWithPrecision(0.0)
4645
.containsExactly(3, 2, 4, 7.5);
4746
Assertions.assertThat(result.getFreeTerm()).isEqualTo(20);
@@ -53,7 +52,7 @@ public void subtract_ThenSubtractingEquations()
5352
// when
5453
Equation result = testObject.subtract(Equation.of(new double[]{1, -1, 4, 10}, 5));
5554
// then
56-
Assertions.assertThat(coefficients(result))
55+
Assertions.assertThat(result.getCoefficients())
5756
.usingComparatorWithPrecision(0.0)
5857
.containsExactly(1, 4, -4, -12.5);
5958
Assertions.assertThat(result.getFreeTerm()).isEqualTo(10);
@@ -65,7 +64,7 @@ public void multiply_WhenConstantIsNonZero_ThenMultiplyingEachCoefficient()
6564
// when
6665
Equation result = testObject.multiply(2);
6766
// then
68-
Assertions.assertThat(coefficients(result))
67+
Assertions.assertThat(result.getCoefficients())
6968
.usingComparatorWithPrecision(0.0)
7069
.containsExactly(4, 6, 0, -5);
7170
Assertions.assertThat(result.getFreeTerm()).isEqualTo(30);
@@ -86,7 +85,7 @@ public void divide_WhenConstantIsNonZero_ThenDividingEachCoefficient()
8685
// when
8786
Equation result = testObject.divide(-2);
8887
// then
89-
Assertions.assertThat(coefficients(result))
88+
Assertions.assertThat(result.getCoefficients())
9089
.usingComparatorWithPrecision(0.0)
9190
.containsExactly(-1, -1.5, 0, 1.25);
9291
Assertions.assertThat(result.getFreeTerm()).isEqualTo(-7.5);
@@ -127,9 +126,4 @@ public void hasSolution_WhenNotSolution_ThenFalse()
127126
// then
128127
Assertions.assertThat(result).isFalse();
129128
}
130-
131-
private double[] coefficients(Equation equation)
132-
{
133-
return IntStream.range(0, equation.size()).mapToDouble(equation::getCoefficient).toArray();
134-
}
135129
}

0 commit comments

Comments
 (0)