/* ## class FBanded ## ## This class holds the frame for matrices stored in banded form. ## It also contains the Gaussian routines for banded matrices. ## */ package edu.rice.linpack.Matrix.FMatrix; import edu.rice.linpack.LNumber.*; import edu.rice.linpack.util.*; import edu.rice.linpack.Vector.*; public class FBanded extends FMatrix { protected int mu, ml; public FBanded() { super(); cons(); } public FBanded(int ML, int MU, int columns) { cons(2*ML+MU+1,columns); mu = MU; ml = ML; } // This is for unbanded float arrays // public FBanded(float[][] f, int ML, int MU) { mu = MU; ml = ML; Mat = band(f,ml,mu); rows = Mat.length; cols = Mat[0].length; pivot = new int[cols]; } // This is for banded float arrays // public FBanded(float[][] f, int ML) { cons(f); ml = ML; mu = f.length - 1 - 2*ML; } public FBanded(FFull F, int Ml, int Mu) { mu = Mu; ml = Ml; Mat = band(F.Mat,ml,mu); rows = Mat.length; cols = Mat[0].length; pivot = new int[cols]; } public FBanded(FBanded F) { cons(F); mu = F.mu; ml = F.ml; } private float[][] band(float[][] f, int Ml, int Mu) { int n = f[0].length; float[][] Fband = new float[2*ml+mu+1][n]; int M = Ml + Mu; for(int j=0;j ml) is--; if(j < mu) L++; if(j >= cols-ml-1) L--; } return anorm; } /* Pivots are java based */ public void factor() throws SingularMatrixException { int info = 0; int M = ml + mu + 1; float T; int Ji = Math.min(cols,M) - 1; int io; for(int Jz=mu+1;Jz < Ji;Jz++) { io = M - 1 - Jz; for(int i=io;i < ml;i++) this.Mat[i][Jz] = 0; } int Jz = Ji; int Ju = 0; /* Gaussian elimination with partial pivoting */ int colsm = cols - 1; if(cols > 1) { int kp; for(int k=0;k Math.abs(this.Mat[M][k])) { float S = Math.abs(this.Mat[M][k])/Math.abs(ek-Z[k]); FUtil.scal(cols,S,Z,1); ek *= S; } float wk = ek - Z[k]; float wkm = -ek - Z[k]; float S = Math.abs(wk); float SM = Math.abs(wkm); if(this.Mat[M][k] != 0) { wk = wk/this.Mat[M][k]; wkm = wkm/this.Mat[M][k]; } else { wk = 1; wkm = 1; } int kp = k + 1; Ju = Math.min(Math.max(Ju,mu+pivot[k]+1),cols); int MM = M-1; if(kp < Ju) { for(int j=kp;j=0;k--) { int lm = Math.min(ml,cols-k-1); if(k < cols-1) Z[k] += this.dot(lm, 1,M+1,k, Z, 1, k+1); if(Math.abs(Z[k]) > 1) { float S = (float)1.0/Math.abs(Z[k]); FUtil.scal(cols,S,Z,1); } int L = pivot[k]; FUtil.swapElems(Z,L,k); } float S = (float)1.0/FUtil.asum(cols,Z,1); FUtil.scal(cols,S,Z,1); } private float solveTransLY(int M, float[] Z) { float ynorm = 1; for(int k=0;k 1) { float S = (float)1.0/Math.abs(Z[k]); FUtil.scal(cols,S,Z,1); ynorm *= S; } } float S = (float)1.0/FUtil.asum(cols,Z,1); FUtil.scal(cols,S,Z,1); ynorm *= S; return ynorm; } float solveUZ(int M, float[] Z, float ynorm){ for(int k=cols-1;k>=0;k--) { if(Math.abs(Z[k]) > Math.abs(this.Mat[M][k])) { float S = Math.abs(this.Mat[M][k])/Math.abs(Z[k]); FUtil.scal(cols,S,Z,1); ynorm *= S; } if(this.Mat[M][k] != 0) Z[k] /= this.Mat[M][k]; else Z[k] = 1; int lm = Math.min(k,M); int la = M - lm; int lz = k - lm; float T = -Z[k]; this.axpy(lm,T,1,la,k,Z,1,lz); } float S = (float)1.0/FUtil.asum(cols,Z,1); FUtil.scal(cols,S,Z,1); ynorm *= S; return ynorm; } public void solve(Vector B) throws WrongDataTypeException { this.solve(B,0); } public void solve(Vector Be, int Job) throws WrongDataTypeException { float[] B = Be.getFloatArray(); int M = mu+ml+1; int nm = cols-1; float T; if(Job == 0) { if(ml != 0) { if(nm > 0) { for(int k=0;k=0;k--) { int lm = Math.min(ml,nm-k); B[k] += this.dot(lm,1,M,k,B,1,k+1); int l = pivot[k]; if(l != k) FUtil.swapElems(B,l,k); } } } return; } void solveTransRY(int M, float[] B) { for(int k=0;k=0;k--) { int LM = Math.min(k,M); int la = M - LM; int lb = k - LM; B[k] /= this.Mat[M][k]; float T = -B[k]; this.axpy(LM,T,1,la,k,B,1,lb); } } public Vector determ() { float[] Det = new float[2]; int M = mu + ml + 1; Det[0] = 1; Det[1] = 0; for(int i=0;i