Skip to content

Commit

Permalink
Merge pull request #65 from GolemIron/features
Browse files Browse the repository at this point in the history
Simple math classes (improvements needed)
  • Loading branch information
Samyssmile authored Oct 26, 2023
2 parents 44e1b8f + 4df0171 commit 24363ad
Show file tree
Hide file tree
Showing 7 changed files with 465 additions and 0 deletions.
13 changes: 13 additions & 0 deletions lib/src/main/java/de/edux/math/Entity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package de.edux.math;

public interface Entity<T> {

T add(T another);

T subtract(T another);

T multiply(T another);

T scalarMultiply(double n);

}
16 changes: 16 additions & 0 deletions lib/src/main/java/de/edux/math/MathUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package de.edux.math;

public final class MathUtil {

public static double[] unwrap(double[][] matrix) {
double[] result = new double[matrix.length * matrix[0].length];
int i = 0;
for (double[] arr : matrix) {
for (double val : arr) {
result[i++] = val;
}
}
return result;
}

}
17 changes: 17 additions & 0 deletions lib/src/main/java/de/edux/math/Validations.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package de.edux.math;

public final class Validations {

public static void size(double[] first, double[] second) {
if (first.length != second.length) {
throw new IllegalArgumentException("sizes mismatch");
}
}

public static void sizeMatrix(double[][] first, double[][] second) {
if (first.length != second.length || first[0].length != second[0].length) {
throw new IllegalArgumentException("sizes mismatch");
}
}

}
161 changes: 161 additions & 0 deletions lib/src/main/java/de/edux/math/entity/Matrix.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package de.edux.math.entity;

import de.edux.math.Entity;
import de.edux.math.MathUtil;
import de.edux.math.Validations;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Matrix implements Entity<Matrix>, Iterable<Double> {

private final double[][] raw;

public Matrix(double[][] matrix) {
this.raw = matrix;
}

@Override
public Matrix add(Matrix another) {
return add(another.raw());
}

public Matrix add(double[][] another) {
Validations.sizeMatrix(raw, another);

double[][] result = new double[raw.length][raw[0].length];

for (int i = 0; i < result.length; i++) {
for (int a = 0; a < result[0].length; a++) {
result[i][a] = raw[i][a] + another[i][a];
}
}

return new Matrix(result);
}

@Override
public Matrix subtract(Matrix another) {
return subtract(another.raw());
}

@Override
public Matrix multiply(Matrix another) {
return multiply(another.raw());
}

public Matrix multiply(double[][] another) {
return null; // TODO optimized algorithm for matrix multiplication
}

@Override
public Matrix scalarMultiply(double n) {
double[][] result = new double[raw.length][raw[0].length];

for (int i = 0; i < result.length; i++) {
for (int a = 0; a < result[0].length; a++) {
result[i][a] = raw[i][a] * n;
}
}

return new Matrix(result);
}

public Matrix subtract(double[][] another) {
Validations.sizeMatrix(raw, another);

double[][] result = new double[raw.length][raw[0].length];

for (int i = 0; i < result.length; i++) {
for (int a = 0; a < result[0].length; a++) {
result[i][a] = raw[i][a] - another[i][a];
}
}

return new Matrix(result);
}

public boolean isSquare() {
return rows() == columns();
}

public int rows() {
return raw.length;
}

public int columns() {
return raw[0].length;
}

public double[][] raw() {
return raw;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Matrix matrix) {
if (matrix.rows() != rows() || matrix.columns() != columns()) {
return false;
}
for (int i = 0; i < raw.length; i++) {
for (int a = 0; a < raw[i].length; a++) {
if (matrix.raw()[i][a] != raw[i][a]) {
return false;
}
}
}
return true;
}
return false;
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder("[").append("\n");
for (int i = 0; i < raw.length; i++) {
builder.append(" ").append("[");
for (int a = 0; a < raw[i].length; a++) {
builder.append(raw[i][a]);
if (a != raw[i].length - 1) {
builder.append(", ");
}
}
builder.append("]");
if (i != raw.length - 1) {
builder.append(",");
}
builder.append("\n");
}
return builder.append("]").toString();
}

@Override
public Iterator<Double> iterator() {
return new MatrixIterator(raw);
}

public static class MatrixIterator implements Iterator<Double> {

private final double[] data;
private int current;

public MatrixIterator(double[][] data) {
this.data = MathUtil.unwrap(data);
this.current = 0;
}

@Override
public boolean hasNext() {
return current < data.length;
}

@Override
public Double next() {
if (!hasNext())
throw new NoSuchElementException();
return data[current++];
}

}

}
154 changes: 154 additions & 0 deletions lib/src/main/java/de/edux/math/entity/Vector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package de.edux.math.entity;

import de.edux.math.Entity;
import de.edux.math.Validations;

import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class Vector implements Entity<Vector>, Iterable<Double> {

private final double[] raw;

public Vector(double[] vector) {
this.raw = vector;
}

@Override
public Vector add(Vector another) {
return add(another.raw());
}

public Vector add(double[] another) {
Validations.size(raw, another);

double[] result = new double[length()];
for (int i = 0; i < result.length; i++) {
result[i] = raw[i] + another[i];
}

return new Vector(result);
}

@Override
public Vector subtract(Vector another) {
return subtract(another.raw());
}

public Vector subtract(double[] another) {
Validations.size(raw, another);

double[] result = new double[length()];
for (int i = 0; i < result.length; i++) {
result[i] = raw[i] - another[i];
}

return new Vector(result);
}

@Override
public Vector multiply(Vector another) {
return multiply(another.raw());
}

public Vector multiply(double[] another) {
Validations.size(raw, another);

double[] result = new double[length()];
for (int i = 0; i < result.length; i++) {
result[i] = raw[i] * another[i];
if (result[i] == 0) { // Avoiding -0 result
result[i] = 0;
}
}

return new Vector(result);
}

@Override
public Vector scalarMultiply(double n) {
double[] result = new double[length()];
for (int i = 0; i < result.length; i++) {
result[i] = raw[i] * n;
if (result[i] == 0) { // Avoiding -0 result
result[i] = 0;
}
}

return new Vector(result);
}

public double dot(Vector another) {
return dot(another.raw());
}

public double dot(double[] another) {
Validations.size(raw, another);

double result = 0;
for (int i = 0; i < raw.length; i++) {
result += raw[i] * another[i];
}

return result;
}

public int length() {
return raw.length;
}

public double[] raw() {
return raw.clone();
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Vector) {
return Arrays.equals(raw, ((Vector) obj).raw());
}
return false;
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder("[");
for (int i = 0; i < raw.length; i++) {
builder.append(raw[i]);
if (i != raw.length - 1) {
builder.append(", ");
}
}
return builder.append("]").toString();
}

@Override
public Iterator<Double> iterator() {
return new VectorIterator(raw);
}

public static class VectorIterator implements Iterator<Double> {

private final double[] data;
private int current;

public VectorIterator(double[] data) {
this.data = data;
this.current = 0;
}

@Override
public boolean hasNext() {
return current < data.length;
}

@Override
public Double next() {
if (!hasNext())
throw new NoSuchElementException();
return data[current++];
}

}

}
Loading

0 comments on commit 24363ad

Please sign in to comment.