public void Dger(double alpha, DoubleMatrix1D x, DoubleMatrix1D y, DoubleMatrix2D A) { Cern.Jet.Math.PlusMult fun = new Cern.Jet.Math.PlusMult(0); for (int i = A.Rows; --i >= 0;) { fun.Multiplicator = alpha * x[i]; A.ViewRow(i).Assign(y, fun); } }
public DoubleMatrix1D Assign(DoubleMatrix1D y, Cern.Jet.Math.PlusMult function, IntArrayList nonZeroIndexes) { CheckSize(y); int[] nonZeroElements = nonZeroIndexes.ToArray(); double multiplicator = function.Multiplicator; if (multiplicator == 0) { // x[i] = x[i] + 0*y[i] return(this); } else if (multiplicator == 1) { // x[i] = x[i] + y[i] for (int index = nonZeroIndexes.Count; --index >= 0;) { int i = nonZeroElements[index]; this[i] = this[i] + y[i]; } } else if (multiplicator == -1) { // x[i] = x[i] - y[i] for (int index = nonZeroIndexes.Count; --index >= 0;) { int i = nonZeroElements[index]; this[i] = this[i] - y[i]; } } else { // the general case x[i] = x[i] + mult*y[i] for (int index = nonZeroIndexes.Count; --index >= 0;) { int i = nonZeroElements[index]; this[i] = this[i] + multiplicator * y[i]; } } return(this); }
public DoubleMatrix1D Assign(DoubleMatrix1D y, Cern.Jet.Math.PlusMult function) { return(Assign(y, function.Apply)); }
public void Solve(DoubleMatrix2D B) { int CUT_OFF = 10; //algebra.property().checkRectangular(LU); int m = M; int n = N; if (B.Rows != m) { throw new ArgumentException("Matrix row dimensions must agree."); } if (!this.IsNonsingular) { throw new ArgumentException("Matrix is singular."); } // right hand side with pivoting // Matrix Xmat = B.getMatrix(piv,0,nx-1); if (this.work1 == null || this.work1.Length < m) { this.work1 = new int[m]; } //if (this.work2 == null || this.work2.Length < m) this.work2 = new int[m]; Algebra.PermuteRows(B, this.piv, this.work1); if (m * n == 0) { return; // nothing to do } int nx = B.Columns; //precompute and cache some views to avoid regenerating them time and again DoubleMatrix1D[] Brows = new DoubleMatrix1D[n]; for (int k = 0; k < n; k++) { Brows[k] = B.ViewRow(k); } // transformations Cern.Jet.Math.Mult div = Cern.Jet.Math.Mult.Div(0); Cern.Jet.Math.PlusMult minusMult = Cern.Jet.Math.PlusMult.MinusMult(0); IntArrayList nonZeroIndexes = new IntArrayList(); // sparsity DoubleMatrix1D Browk = Cern.Colt.Matrix.DoubleFactory1D.Dense.Make(nx); // blocked row k // Solve L*Y = B(piv,:) for (int k = 0; k < n; k++) { // blocking (make copy of k-th row to localize references) Browk.Assign(Brows[k]); // sparsity detection int maxCardinality = nx / CUT_OFF; // == heuristic depending on speedup Browk.GetNonZeros(nonZeroIndexes, null, maxCardinality); int cardinality = nonZeroIndexes.Count; Boolean sparse = (cardinality < maxCardinality); for (int i = k + 1; i < n; i++) { //for (int j = 0; j < nx; j++) B[i][j] -= B[k][j]*LU[i][k]; //for (int j = 0; j < nx; j++) B.set(i,j, B.Get(i,j) - B.Get(k,j)*LU.Get(i,k)); minusMult.Multiplicator = -LU[i, k]; if (minusMult.Multiplicator != 0) { if (sparse) { Brows[i].Assign(Browk, minusMult, nonZeroIndexes); } else { Brows[i].Assign(Browk, minusMult); } } } } // Solve U*B = Y; for (int k = n - 1; k >= 0; k--) { // for (int j = 0; j < nx; j++) B[k][j] /= LU[k][k]; // for (int j = 0; j < nx; j++) B.set(k,j, B.Get(k,j) / LU.Get(k,k)); div.Multiplicator = 1 / LU[k, k]; Brows[k].Assign(div); // blocking if (Browk == null) { Browk = Cern.Colt.Matrix.DoubleFactory1D.Dense.Make(B.Columns); } Browk.Assign(Brows[k]); // sparsity detection int maxCardinality = nx / CUT_OFF; // == heuristic depending on speedup Browk.GetNonZeros(nonZeroIndexes, null, maxCardinality); int cardinality = nonZeroIndexes.Count; Boolean sparse = (cardinality < maxCardinality); //Browk.GetNonZeros(nonZeroIndexes,null); //Boolean sparse = nonZeroIndexes.Count < nx/10; for (int i = 0; i < k; i++) { // for (int j = 0; j < nx; j++) B[i][j] -= B[k][j]*LU[i][k]; // for (int j = 0; j < nx; j++) B.set(i,j, B.Get(i,j) - B.Get(k,j)*LU.Get(i,k)); minusMult.Multiplicator = -LU[i, k]; if (minusMult.Multiplicator != 0) { if (sparse) { Brows[i].Assign(Browk, minusMult, nonZeroIndexes); } else { Brows[i].Assign(Browk, minusMult); } } } } }