Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class matrix {
- private double[][] M;
- private static double epsilon = 1e-14;
- /* construtors */
- public matrix(int n){
- this(n,n);
- }
- public matrix(int n, int m){
- M = new double[n][m];
- }
- public matrix(int n, int m, double d){
- M = new double[n][m];
- for(int i=0;i<n;i++){
- for(int j=0;j<m;j++){
- set(i, j, d);
- }
- }
- }
- public matrix(double[][] t){
- M = new double[t.length][t[0].length];
- for(int i=0;i<t.length;i++){
- for(int j=0;j<t[i].length;j++){
- set(i, j, t[i][j]);
- }
- }
- }
- public matrix(matrix m){
- this(m.M);
- }
- public matrix(matrix m,int sr,int sc,int er,int ec){
- M = new double[er-sr+1][ec-sc+1];
- int r=0,c=0;
- for(int i=sr;i<=er && i<m.rlen();i++){
- for(int j=sc;j<=ec && j<m.clen();j++){
- set(r, c, m.get(i, j));
- c++;
- }
- r++; c=0;
- }
- }
- /* */
- public static matrix rand(int n, int m, double min, double max, int round){
- matrix mat = new matrix(n,m);
- double nb;
- double p = Math.pow(10, round);
- for(int i=0;i<n;i++){
- for(int j=0;j<n;j++){
- nb = Math.random()*(max-min+1)+min;
- mat.set(i, j, Math.round(nb*p)/p);
- }
- }
- return mat;
- }
- public static matrix rand(int n, int m){
- return matrix.rand(n,m,0,100,2);
- }
- @Override
- public String toString(){
- String str = "[";
- for(int i=0;i<M.length-1;i++){
- str += "[";
- for(int j=0;j<M[i].length-1;j++){
- str += M[i][j]+", ";
- }
- str += M[i][M[i].length-1];
- str += "], ";
- }
- str += "[";
- for(int j=0;j<M[M.length-1].length-1;j++){
- str += M[M.length-1][j]+", ";
- }
- str += M[M.length-1][M[M.length-1].length-1];
- str += "]";
- str += "]";
- return str;
- }
- public double get(int i, int j){
- return M[i][j];
- }
- public final void set(int i, int j, double n){
- if( n < epsilon && n > -epsilon )
- M[i][j] = 0;
- else
- M[i][j] = n;
- }
- public int rlen(){
- return M.length;
- }
- public int clen(){
- return M[0].length;
- }
- public matrix add(matrix b){
- matrix m = new matrix(rlen(), clen());
- for(int i=0;i<m.rlen();i++){
- for(int j=0;j<m.clen();j++){
- m.set(i, j, get(i,j)+b.get(i, j));
- }
- }
- return m;
- }
- public matrix minus(matrix b){
- matrix m = new matrix(rlen(), clen());
- for(int i=0;i<m.rlen();i++){
- for(int j=0;j<m.clen();j++){
- m.set(i, j, get(i,j)-b.get(i, j));
- }
- }
- return m;
- }
- public matrix mul(matrix b){
- // condition this.clen = b.rlen
- matrix m = new matrix(rlen(), b.clen());
- for(int i=0;i<m.rlen();i++){
- for(int j=0;j<m.clen();j++){
- double rij = 0;
- for(int ki=0;ki<clen();ki++){
- rij += get(i,ki)*b.get(ki,j);
- }
- m.set(i, j, rij);
- }
- }
- return m;
- }
- public static double pow2(double a, int b){
- if(b==0)
- return 1;
- double r = pow2(a,b/2);
- if(b%2==0)
- return r*r;
- else
- return r*r*a;
- }
- // next or equal power of two of n nepot(4)=4 && nepot(5)=8
- public static int nepot(int n){
- double d = Math.log(n)/Math.log(2);
- int p = (int) d;
- if( p==d )
- return n;
- else
- return (int)pow2(2,p+1);
- }
- public matrix strassen(matrix m){
- int n=m.rlen();
- if(n<=32)
- return mul(m);
- matrix res = new matrix(n,n);
- // find next power of 2
- int nepot = nepot(n);
- matrix m1,m2,m3,m4,m5,m6,m7,a11,a12,a21,a22,b11,b12,b21,b22;
- a11 = new matrix(this,0,0,nepot/2-1,nepot/2-1);
- a12 = new matrix(this,0,nepot/2,nepot/2-1,nepot-1);
- a21 = new matrix(this,nepot/2,0,nepot-1,nepot/2-1);
- a22 = new matrix(this,nepot/2,nepot/2,nepot-1,nepot-1);
- b11 = new matrix(m,0,0,nepot/2-1,nepot/2-1);
- b12 = new matrix(m,0,nepot/2,nepot/2-1,nepot-1);
- b21 = new matrix(m,nepot/2,0,nepot-1,nepot/2-1);
- b22 = new matrix(m,nepot/2,nepot/2,nepot-1,nepot-1);
- m1 = a11.add(a22).strassen(b11.add(b22));
- m2 = a21.add(a22).strassen(b11);
- m3 = a11.strassen(b12.minus(b22));
- m4 = a22.strassen(b21.minus(b11));
- m5 = a11.add(a12).strassen(b22);
- m6 = a21.minus(a11).strassen(b11.add(b12));
- m7 = a12.minus(a22).strassen(b21.add(b22));
- matrix c11,c12,c22,c21;
- c11 = m1.add(m4).minus(m5).add(m7);
- c12 = m3.add(m5);
- c21 = m2.add(m4);
- c22 = m1.minus(m2).add(m3).add(m6);
- for(int i=0;i<c11.rlen();i++){
- for(int j=0;j<c11.rlen();j++){
- res.set(i, j, c11.get(i, j));
- }
- }
- for(int i=0;i<c11.rlen();i++){
- for(int j=c11.rlen();j<n;j++){
- res.set(i, j, c12.get(i, j-c11.rlen()));
- }
- }
- for(int i=c11.rlen();i<n;i++){
- for(int j=0;j<c11.rlen();j++){
- res.set(i, j, c21.get(i-c11.rlen(), j));
- }
- }
- for(int i=c11.rlen();i<n;i++){
- for(int j=c11.rlen();j<n;j++){
- res.set(i, j, c22.get(i-c11.rlen(), j-c11.rlen()));
- }
- }
- return res;
- }
- public matrix mul(double c){
- matrix m = new matrix(this);
- for(int i=0;i<rlen();i++){
- for(int j=0;j<clen();j++){
- m.set(i, j, c*m.get(i, j));
- }
- }
- return m;
- }
- public matrix transpose(){
- matrix T = new matrix(clen(), rlen());
- for(int i=0;i<rlen();i++){
- for(int j=0;j<clen();j++){
- T.set(j, i, get(i, j));
- }
- }
- return T;
- }
- // row basic operations
- public matrix rowSwitching(int li, int lj){
- double temp;
- for(int i=0;i<clen();i++){
- temp = get(li, i);
- set(li, i, get(lj, i));
- set(lj, i, temp);
- }
- return this;
- }
- public matrix rowMultiplication(int li, double k){
- for(int i=0;i<clen();i++){
- set(li, i, get(li, i)*k);
- }
- return this;
- }
- public matrix rowAddition(int li, int lj, double k){
- // li <- li + k*lj && k <> 0
- for(int i=0;i<clen();i++){
- set(li, i, get(li, i)+get(lj, i)*k);
- }
- return this;
- }
- public matrix submatrix(int si, int sj){
- matrix m = new matrix(rlen()-1, clen()-1);
- int ki=0, kj=0;
- for(int i=0;i<rlen();i++){
- if( si==i ){
- continue;
- }
- for(int j=0;j<clen();j++){
- if( sj!=j ){
- m.set(ki, kj, get(i, j));
- if( kj == m.clen()-1 ){
- kj = 0;
- }else{
- kj++;
- }
- }
- }
- ki++;
- }
- return m;
- }
- public double trace(){
- double tr = 0;
- for(int i=0;i<rlen();i++){
- tr += get(i, i);
- }
- return tr;
- }
- public double det(){
- if( clen()==1 && rlen()==1 )
- return get(0, 0);
- double det = 0;
- int p = 1;
- for(int i=0;i<rlen();i++){
- if( get(0, i)!=0 )
- det += p*get(0,i)*submatrix(0, i).det();
- p *= -1;
- }
- return det;
- }
- public matrix inverse(){
- matrix inv = new matrix(rlen(), clen());
- double det = det(); int p;
- for(int i=0;i<rlen();i++){
- for(int j=0;j<clen();j++){
- p = ( (i+j)%2==0 ) ? 1 : -1;
- inv.set(i, j, p*submatrix(j, i).det()/det);
- }
- }
- return inv;
- }
- public boolean isInversible(){
- return det() != 0;
- }
- private static boolean equalsDouble(double a, double b){
- return Math.abs( a-b )<epsilon;
- }
- public boolean equals(matrix L){
- if( L.rlen()!=rlen() || L.clen()!=clen() )
- return false;
- for(int i=0;i<L.rlen();i++){
- for(int j=0;j<L.clen();j++){
- if( !equalsDouble(L.get(i, j), get(i, j)) )
- return false;
- }
- }
- return true;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment