Add new symmetric matrix class and so a new trinagular number method in Sequence class. Modify constructor and the addition routine in matrix classes. Add a new property to WObjekt to store the number of operations.

This commit is contained in:
2014-05-12 11:20:52 +02:00
parent d15274fa28
commit e06b6cf84b
10 changed files with 375 additions and 61 deletions

View File

@@ -778,6 +778,18 @@ final public class Maths{
return sum; return sum;
} }
/**
* @param a
* @return sum of all values in array.
*/
public static Integer sum(Integer[] a) {
int i;
Integer sum = 0;
for(i=0; i<a.length; i++)
sum += a[i];
return sum;
}
/** /**
* @param a array * @param a array
* @param is first index * @param is first index

View File

@@ -2,7 +2,41 @@ package math;
import math.number.Rational; import math.number.Rational;
class Sequence { public class Sequence {
/**
* Triangular numbers.
* 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120 &hellip;
* T<sub>n</sub> = &sum;k = 1 + 2 + 3 + 4 + &hellip; + n = 0.5*n*(n+1).
* @param n
* @return
*/
public static int triangularNumber(int n){
return polygonalNumber(3,n);
}
/**
* Triangular roots.
* @param x
* @return
*/
public static double triangularRoot(int x){
return (Math.sqrt(8*x+1)-1)/2;
}
/**
* (s-2)*n*(n-1)/2+n
* @param s
* @param n
* @return
*/
public static int polygonalNumber(int s, int n){
switch(s){
case 3: return n*(n+1)/2;
case 4: return n*n;
default: return n*((s-2)*n-s)/2;
}
}
/** /**
* Prints out binomial coefficients such that such that a[N][k] contains * Prints out binomial coefficients such that such that a[N][k] contains

View File

@@ -124,6 +124,7 @@ public class Series{
/** /**
* The sum of a geometric series. * The sum of a geometric series.
* a+ar+ar<sup>2</sup>+ar<sup>3</sup>+&hellip;
* @param a start term * @param a start term
* @param r common ratio * @param r common ratio
* @return sum * @return sum
@@ -136,6 +137,7 @@ public class Series{
/** /**
* The sum of a geometric series. * The sum of a geometric series.
* a+ar+ar<sup>2</sup>+ar<sup>3</sup>+&hellip;
* @param a start term * @param a start term
* @param r common ratio * @param r common ratio
* @return sum * @return sum
@@ -148,6 +150,7 @@ public class Series{
/** /**
* The sum of a geometric series. * The sum of a geometric series.
* a+ar+ar<sup>2</sup>+ar<sup>3</sup>+&hellip;+ar<sup>n-1</sup>.
* @param a start term * @param a start term
* @param r common ratio * @param r common ratio
* @param n first n terms * @param n first n terms

View File

@@ -1,5 +1,7 @@
package math.matrix; package math.matrix;
import exception.IllegalDimensionException;
/** /**
* 2D diagonal matrix object d<sub>ij</sub>&isin;&#x211D;, i&ne;j=0 * 2D diagonal matrix object d<sub>ij</sub>&isin;&#x211D;, i&ne;j=0
* with 2 rows and 2 columns * with 2 rows and 2 columns
@@ -17,6 +19,12 @@ public class Diagonal2D extends Matrix2D {
n = 2; n = 2;
data = new double[2]; data = new double[2];
} }
public Diagonal2D(double... i){
m = 2;
n = 2;
data = i;
}
/** /**
* Generate an n-by-n identity matrix. * Generate an n-by-n identity matrix.
@@ -35,6 +43,34 @@ public class Diagonal2D extends Matrix2D {
public void set(int i, double d){ public void set(int i, double d){
data[i] = d; data[i] = d;
} }
/**
* Subtract two matrices of the same dimension (entrywise subtraction).
* The subtraction of two m-by-n matrices <b>A</b> and <b>B</b>,
* is again an m-by-n matrix computed by subtracting corresponding elements.
* @param B matrix
* @return <b>C</b> = <b>A</b> - <b>B</b>, entrywise subtracted matrix
* @throws IllegalDimensionException
*/
public Matrix minus(Matrix B) throws IllegalDimensionException{
checkDimensions(B);
int i,j;
Matrix c = createAddition(B);
// System.out.println(this instanceof Diagonal2D);
// System.out.println(this);
// System.out.println(B instanceof Diagonal2D);
// System.out.println(B);
// System.out.println(c instanceof Diagonal2D);
// System.out.println(c);
if(B instanceof Diagonal)
for(i=0; i<n; i++)
c.minus(i, i, ((Diagonal) B).get(i));
else
for(i=0; i<m; i++)
for(j=0; j<n; j++)
c.minus(i,j, B.get(i,j));
return c;
}
public String toString(){ public String toString(){
return Matrix2D.diag(data).toString(); return Matrix2D.diag(data).toString();

View File

@@ -27,7 +27,7 @@ import exception.SingularException;
*/ */
public class Matrix extends WObject implements Cloneable, Serializable{ public class Matrix extends WObject implements Cloneable, Serializable{
enum Flag{Square, Symmetric} // TODO: subclass? enum Flag{Square}
/** /**
* UID * UID
@@ -235,7 +235,15 @@ public class Matrix extends WObject implements Cloneable, Serializable{
this(a.n, a.get()); this(a.n, a.get());
} }
public Matrix create(int m, int n){ private Matrix copy(){
if(this instanceof TensorII2D) return new TensorII2D(this);
if(this instanceof Matrix2D) return new Matrix2D(this);
if(this instanceof Matrix3D) return new Matrix3D(this);
if(this instanceof Diagonal) return new Diagonal(this);
else return new Matrix(this);
}
private Matrix create(int m, int n){
if(this instanceof TensorII2D) return new TensorII2D(); if(this instanceof TensorII2D) return new TensorII2D();
if(this instanceof TensorII) return new TensorII(); if(this instanceof TensorII) return new TensorII();
if(this instanceof Matrix3D) return new Matrix3D(n); if(this instanceof Matrix3D) return new Matrix3D(n);
@@ -245,22 +253,24 @@ public class Matrix extends WObject implements Cloneable, Serializable{
else return new Matrix(m,n); else return new Matrix(m,n);
} }
public Matrix create(int m, int n, Matrix B){ protected Matrix createAddition(Matrix B){
if(m == 2 && B.n == 2) return new TensorII2D(); if(this instanceof Symmetric && B instanceof Symmetric) return new Symmetric(getN());
if(m == 3 && B.n == 3) return new TensorII(); if(this instanceof Diagonal && B instanceof Diagonal) return new Diagonal(getM(),getN());
if(this instanceof Matrix3D) return new Matrix3D(n); if(this instanceof Matrix3D && B instanceof Matrix3D) return new Matrix3D(getN());
if(this instanceof Matrix2D) return new Matrix2D(n); if(this instanceof Matrix2D && B instanceof Matrix2D) return new Matrix2D(getN());
if(this instanceof Matrix3D) return new Matrix3D(n); if(this instanceof TensorII2D && B instanceof TensorII2D) return new TensorII2D();
if(this instanceof Diagonal) return new Diagonal(m,n); else return new Matrix(getM(),getN());
else return new Matrix(m,n);
} }
public Matrix create(Matrix B){ private Matrix createMultiplication(Matrix B){
if(this instanceof TensorII2D) return new TensorII2D(B); // System.out.println(n);
if(this instanceof Matrix2D) return new Matrix2D(B); if(m == 2 && B.n == 2) return new TensorII2D();
if(this instanceof Matrix3D) return new Matrix3D(B); if(m == 3 && B.n == 3) return new TensorII();
if(this instanceof Diagonal) return new Diagonal(B); if(this instanceof Matrix3D) return new Matrix3D(B.n);
else return new Matrix(B); if(this instanceof Matrix2D) return new Matrix2D(B.n);
if(this instanceof Matrix3D) return new Matrix3D(B.n);
if(this instanceof Diagonal) return new Diagonal(m,B.n);
else return new Matrix(m,B.n);
} }
private Vector create(int n){ private Vector create(int n){
@@ -470,6 +480,16 @@ public class Matrix extends WObject implements Cloneable, Serializable{
return c; return c;
} }
/**
* Get the element A<sub>i</sub> at given index i
* @param i index
* @return the value at the given index i
* @throws IllegalDimensionException
*/
protected double get(int i){
return data[i];
}
/** /**
* Get the element A<sub>ij</sub> at given row i and column j * Get the element A<sub>ij</sub> at given row i and column j
* @param i row * @param i row
@@ -797,7 +817,7 @@ public class Matrix extends WObject implements Cloneable, Serializable{
* @param j column * @param j column
* @param b scalar * @param b scalar
*/ */
public void plus(int i, int j, double b){ protected void plus(int i, int j, double b){
set(i,j, get(i,j)+b); set(i,j, get(i,j)+b);
} }
@@ -812,14 +832,20 @@ public class Matrix extends WObject implements Cloneable, Serializable{
public Matrix plus(Matrix B) throws IllegalDimensionException{ public Matrix plus(Matrix B) throws IllegalDimensionException{
checkDimensions(B); checkDimensions(B);
int i,j; int i,j;
Matrix c = create(this); Matrix c = createAddition(B);
c.newOperation();
if(B instanceof Diagonal) if(B instanceof Diagonal)
for(i=0; i<n; i++) for(i=0; i<m; i++)
c.plus(i, i, ((Diagonal) B).get(i)); for(j=0; j<n; j++){
c.set(i, j, get(i,j)+((Diagonal) B).get(i));
c.operate();
}
else else
for(i=0; i<m; i++) for(i=0; i<m; i++)
for(j=0; j<n; j++) for(j=0; j<n; j++){
c.plus(i,j, B.get(i,j)); c.set(i,j, get(i,j)+B.get(i,j));
c.operate();
}
return c; return c;
} }
@@ -876,16 +902,22 @@ public class Matrix extends WObject implements Cloneable, Serializable{
public Matrix minus(Matrix B) throws IllegalDimensionException{ public Matrix minus(Matrix B) throws IllegalDimensionException{
checkDimensions(B); checkDimensions(B);
int i,j; int i,j;
Matrix c = create(B); Matrix c = createAddition(B);
System.out.println(this); //System.out.println(this instanceof Diagonal2D);
System.out.println(B); //System.out.println(this);
//System.out.println(B);
if(B instanceof Diagonal) if(B instanceof Diagonal)
for(i=0; i<n; i++) for(i=0; i<m; i++)
c.minus(i, i, ((Diagonal) B).get(i)); for(j=0; j<n; j++){
c.set(i, j, get(i,j));
if(i==j)
c.set(i, j, get(i,j)-((Diagonal) B).get(i));
}
else else
for(i=0; i<m; i++) for(i=0; i<m; i++)
for(j=0; j<n; j++) for(j=0; j<n; j++){
c.minus(i,j, B.get(i,j)); c.set(i,j, get(i,j)-B.get(i,j));
}
return c; return c;
} }
@@ -1007,7 +1039,10 @@ public class Matrix extends WObject implements Cloneable, Serializable{
public Matrix times(Matrix B) throws IllegalDimensionException{ public Matrix times(Matrix B) throws IllegalDimensionException{
int i,j,k; int i,j,k;
if(n != B.m) throw new IllegalDimensionException("Inner matrix dimensions must agree."); if(n != B.m) throw new IllegalDimensionException("Inner matrix dimensions must agree.");
Matrix c = create(m,B.n,B); Matrix c = createMultiplication(B);
// System.out.println("times\n" + this);
// System.out.println(B);
// System.out.println(c);
if(B instanceof Diagonal) if(B instanceof Diagonal)
for(i=0; i<c.m; i++) for(i=0; i<c.m; i++)
for(j=0; j<c.n; j++) for(j=0; j<c.n; j++)
@@ -1603,7 +1638,7 @@ public class Matrix extends WObject implements Cloneable, Serializable{
throw new IllegalArgumentException("Illegal matrix dimensions."); throw new IllegalArgumentException("Illegal matrix dimensions.");
// create copies of the data // create copies of the data
Matrix A = create(this); Matrix A = copy();
Vector B = create(b); Vector B = create(b);
// Gaussian elimination with partial pivoting // Gaussian elimination with partial pivoting
@@ -1696,7 +1731,7 @@ public class Matrix extends WObject implements Cloneable, Serializable{
*/ */
public Matrix eigenvalues(){ public Matrix eigenvalues(){
if(eig == null) eig(); if(eig == null) eig();
return create(eig.getD()); return new Matrix(eig.getD());
} }
/** /**
@@ -1724,7 +1759,7 @@ public class Matrix extends WObject implements Cloneable, Serializable{
*/ */
public Matrix eigenvectors(){ public Matrix eigenvectors(){
if(eig == null) eig(); if(eig == null) eig();
return create(eig.getV()); return new Matrix(eig.getV());
} }
/** /**
@@ -1886,7 +1921,7 @@ public class Matrix extends WObject implements Cloneable, Serializable{
* Check if size(A) == size(B) * Check if size(A) == size(B)
* @throws IllegalDimensionException * @throws IllegalDimensionException
**/ **/
private void checkDimensions(Matrix b) throws IllegalDimensionException { protected void checkDimensions(Matrix b) throws IllegalDimensionException {
if(b.m != m || b.n != n) if(b.m != m || b.n != n)
throw new IllegalDimensionException("Two matrices have to be the same dimension."); throw new IllegalDimensionException("Two matrices have to be the same dimension.");
} }
@@ -2235,31 +2270,63 @@ public class Matrix extends WObject implements Cloneable, Serializable{
Matrix.setSupressErrorMessage(true); Matrix.setSupressErrorMessage(true);
Matrix A, B, C, D; Matrix A, B, C, D;
boolean test;
A = Matrix.random(5, 5); A = new Matrix(new double[][]{{3,1,2},{2,0,5},{1,2,3}});
A.setName("A").println(); B = new Matrix(new double[][]{{3,1,2},{2,0,5},{5,1,7}});
System.out.println(A.setName("A"));
System.out.println(B.setName("B"));
test = A.plus(B).equals(new Matrix(new double[][]{{6,2,4},{4,0,10},{6,3,10}}));
if(test) System.out.println("A+B : test successful");
else System.err.println("A+B : test faild");
System.out.println("Operations: "+A.plus(B).getOperationsTotal());
// System.out.println(A.plus(B));
test = A.minus(B).equals(new Matrix(new double[][]{{0,0,0},{0,0,0},{-4,1,-4}}));
if(test) System.out.println("A-B : test successful");
else System.err.println("A-B : test faild");
// System.out.println(A.minus(B));
A.swap(1, 2); test = A.transpose().equals(new Matrix(new double[][]{{3,2,1},{1,0,2},{2,5,3}}));
System.out.println("A.swap(1, 2)"); if(test) System.out.println("A' : test successful");
A.println(); else System.err.println("A' : test faild");
// System.out.println(A.transpose());
B = A.transpose();
System.out.println("A' = \n" + B.setName("B")); test = A.swap(1, 2).equals(new Matrix(new double[][]{{3,1,2},{1,2,3},{2,0,5}}));
if(test) System.out.println("A.swap(1, 2) : test successful");
else System.err.println("A.swap(1, 2) : faild");
A.swap(1, 2);
// A.println();
C = Matrix.identity(5); C = Matrix.identity(5);
System.out.println("identity(5) = \n"+C.setName("C")); test = Matrix.identity(5).equals(new Diagonal(1,1,1,1,1));
if(test) System.out.println("identity(5) : test successful");
else System.err.println("identity(5) : test faild");
System.out.println(A); // System.out.println(A);
test = A.times(B).equals(new Matrix(new double[][]{{21,5,25},{31,7,39},{22,4,33}}));
if(test) System.out.println("A*B : test successful");
else System.err.println("A*B : test faild");
// System.out.println(A.times(B));
// System.out.println(B.times(A));
// shouldn't be equal since AB != BA in general // shouldn't be equal since AB != BA in general
System.out.println("A*B =? B*A : \n"+A.times(B).equals(B.times(A))); test = A.times(B).equals(B.times(A));
System.out.println(A); if(!test) System.out.println("A*B =? B*A : "+A.times(B).equals(B.times(A)) + " -> test successful");
else System.err.println("A*B =? B*A : "+A.times(B).equals(B.times(A)) + " -> test faild");
// System.out.println(A);
D = Matrix.random(5, 5);
// D.setName("D").println();
Matrix f = Matrix.random(5, 1); Matrix f = Matrix.random(5, 1);
System.out.println("random(5, 1) = \n"+f.setName("f")); System.out.println("random(5, 1) = \n"+f.setName("f"));
Matrix x = A.solve(f); Matrix x = D.solve(f);
System.out.println("A^-1*f = \n"+x.setName("x")); System.out.println("D^-1*f = \n"+x.setName("x"));
Matrix2D a = new Matrix2D(0,1,1,0); Matrix2D a = new Matrix2D(0,1,1,0);
System.out.println(a.setName("a")); System.out.println(a.setName("a"));
@@ -2413,6 +2480,7 @@ public class Matrix extends WObject implements Cloneable, Serializable{
Vector2D v = new Vector2D(1,1); Vector2D v = new Vector2D(1,1);
Vector2D w = new Vector2D(0,1); Vector2D w = new Vector2D(0,1);
System.out.println(v.setName("v"));
P = (Matrix2D) Matrix2D.mirror(v); P = (Matrix2D) Matrix2D.mirror(v);
System.out.println("Pw = "); System.out.println("Pw = ");
P.times(w).println(); P.times(w).println();
@@ -2487,7 +2555,7 @@ public class Matrix extends WObject implements Cloneable, Serializable{
D = new Diagonal(2.,3); D = new Diagonal(2.,3);
System.out.println(A); System.out.println(A);
System.out.println(D); System.out.println(D.setName("D"));
System.out.println(A.plus(D)); System.out.println(A.plus(D));
Matrix I = Matrix.identity(2); Matrix I = Matrix.identity(2);

View File

@@ -214,6 +214,7 @@ public class Matrix2D extends Matrix{
*/ */
public static Matrix2D mirror(Vector v) throws IllegalDimensionException{ public static Matrix2D mirror(Vector v) throws IllegalDimensionException{
// P = I - alpha v v'; alpha = 2 / (v'v) // P = I - alpha v v'; alpha = 2 / (v'v)
//System.out.println(Diagonal2D.identity(v.n()) instanceof Diagonal2D);
return (Matrix2D) Diagonal2D.identity(v.n()).minus(v.tensorProduct(v).times(2/v.dot(v))); return (Matrix2D) Diagonal2D.identity(v.n()).minus(v.tensorProduct(v).times(2/v.dot(v)));
} }

View File

@@ -18,7 +18,7 @@ import math.Maths;
* returns false. * returns false.
* @author Daniel Weschke * @author Daniel Weschke
*/ */
public class QRDecomposition implements Serializable { public class QRDecomposition extends Matrix implements Serializable {
/** /**
* UID * UID

View File

@@ -0,0 +1,104 @@
package math.matrix;
import exception.IllegalDimensionException;
import math.Sequence;
/**
* Symmetric matrix object d<sub>ij</sub>=d<sub>ji</sub>&isin;&#x211D;
* with n rows and n columns
* @author Daniel Weschke
*/
public class Symmetric extends Matrix {
/**
* UID
*/
private static final long serialVersionUID = -3506578822884073555L;
public Symmetric(int n){
this.m = n;
this.n = n;
data = new double[Sequence.triangularNumber(n)];
}
public Symmetric(double... d){
this((int)Math.ceil(Sequence.triangularRoot(d.length)));
int i;
for(i=0; i<d.length; i++)
set(i, d[i]);
}
public Matrix set(int i, double d){
data[i] = d;
return this;
}
public Matrix set(int i, int j, double d){
data[index(i,j)] = d;
return this;
}
public double get(int i, int j){
return get(index(i,j));
}
private int index(int i, int j){
return i>j?Sequence.triangularNumber(i)+j:i+Sequence.triangularNumber(j);
}
/**
* Adds two matrices of the same dimension (entrywise addition).
* The addition of two n-by-n matrices <b>A</b> and <b>B</b>,
* is again an n-by-n matrix computed by adding corresponding elements.
* @param B matrix
* @return <b>C</b> = <b>A</b> + <b>B</b>, entrywise summarized matrix
* @throws IllegalDimensionException
*/
public Matrix plus(Matrix B) throws IllegalDimensionException{
checkDimensions(B);
int i,j;
Matrix c = createAddition(B);
c.newOperation();
if(B instanceof Diagonal)
for(i=0; i<m; i++)
for(j=i; j<n; j++){
c.set(i, j, get(i,j)+((Diagonal) B).get(i));
c.operate();
}
else if(B instanceof Symmetric)
for(i=0; i<m; i++)
for(j=i; j<n; j++){
c.set(i,j, get(i,j)+B.get(i,j));
c.operate();
}
else
for(i=0; i<m; i++)
for(j=0; j<n; j++){
c.set(i,j, get(i,j)+B.get(i,j));
c.operate();
}
// System.out.println(this instanceof Symmetric);
// System.out.println(B instanceof Symmetric);
return c;
}
public static void main(String[] args){
Symmetric s1 = new Symmetric(1.);
System.out.println(s1);
Symmetric s2 = new Symmetric(1., 2.);
System.out.println(s2);
Symmetric s3 = new Symmetric(1., 2., 3.);
System.out.println(s3);
Symmetric s4 = new Symmetric(1., 2., 3., 4.);
System.out.println(s4);
System.out.println(s4.get(0,2));
System.out.println(s4.get(2,0));
try {
System.out.println(s2.plus(s3));
System.out.println("Operations: "+s2.plus(s3).getOperationsTotal());
System.out.println(s2.minus(s3));
} catch (IllegalDimensionException e) {
e.printStackTrace();
}
}
}

View File

@@ -11,6 +11,10 @@ public class TensorII extends Matrix3D {
*/ */
private static final long serialVersionUID = -5664678448598889794L; private static final long serialVersionUID = -5664678448598889794L;
public TensorII() {
super(3);
}
public static void main(String[] args) { public static void main(String[] args) {
} }

View File

@@ -1,11 +1,52 @@
package thisandthat; package thisandthat;
import java.util.ArrayList;
import java.util.Arrays;
import math.Maths;
/** /**
* @author Daniel Weschke * @author Daniel Weschke
*/ */
public class WObject { public class WObject {
private static boolean supressErrorMessage = false; private static boolean supressErrorMessage = false;
private String name; private String name;
private ArrayList<Integer> operations = new ArrayList<Integer>();
private Integer[] convertedArray;
private boolean justConverted;
public String getName() {
return name;
}
public WObject setName(String name) {
this.name = name;
return this;
}
public Integer[] getOperations(){
if(!justConverted){
Integer[] itemArray = new Integer[operations.size()];
convertedArray = operations.toArray(itemArray);
justConverted = true;
}
return convertedArray;
}
public int getOperationsTotal(){
return Maths.sum(getOperations());
}
public void newOperation(){
operations.add(0);
justConverted = false;
}
public void operate(){
int index = operations.size()-1;
operations.set(index,operations.get(index)+1);
justConverted = false;
}
public static boolean isSupressErrorMessage() { public static boolean isSupressErrorMessage() {
return supressErrorMessage; return supressErrorMessage;
@@ -26,15 +67,6 @@ public class WObject {
public static <T> T last(T[] array) { public static <T> T last(T[] array) {
return array[array.length - 1]; return array[array.length - 1];
} }
public String getName() {
return name;
}
public WObject setName(String name) {
this.name = name;
return this;
}
/** /**
* The declaration of that method is: * The declaration of that method is:
@@ -67,6 +99,26 @@ public class WObject {
WObject obj = new WObject(); WObject obj = new WObject();
obj.setName("one"); obj.setName("one");
obj.println(); obj.println();
obj.newOperation();
System.out.print(Arrays.toString(obj.getOperations()));
System.out.println(" tot: "+obj.getOperationsTotal());
obj.operate();
System.out.print(Arrays.toString(obj.getOperations()));
System.out.println(" tot: "+obj.getOperationsTotal());
obj.operate();
System.out.print(Arrays.toString(obj.getOperations()));
System.out.println(" tot: "+obj.getOperationsTotal());
obj.newOperation();
System.out.print(Arrays.toString(obj.getOperations()));
System.out.println(" tot: "+obj.getOperationsTotal());
obj.operate();
System.out.print(Arrays.toString(obj.getOperations()));
System.out.println(" tot: "+obj.getOperationsTotal());
obj.operate();
System.out.print(Arrays.toString(obj.getOperations()));
System.out.println(" tot: "+obj.getOperationsTotal());
} }
} }