public static int expb_df(PZMath_vector x, object param, PZMath_matrix J) { int n = (param as TestNonlinearLeastSquareFitParam).n; double[] sigma = (param as TestNonlinearLeastSquareFitParam).sigma; double A = x[0]; double lambda = x[1]; int i; for (i = 0; i < n; i++) { // Jacobian matrix J(i, j) = dfi / dxj // where fi = (Yi - yi) / sigma[i] // Yi = A * exp(-lambda * i) + b // and the xj are the parameters (A, lambda, b) double t = (double)i; double s = sigma[i]; double e = System.Math.Exp(-lambda * t); J[i, 0] = e / s; J[i, 1] = -t * A * e / s; J[i, 2] = 1 / s; } return PZMath_errno.PZMath_SUCCESS; }
public static int BidiagDecomp(PZMath_matrix A, PZMath_vector tau_U, PZMath_vector tau_V) { if (A.RowCount < A.ColumnCount) PZMath_errno.ERROR ("PZMath_linalg::BidiagDecomp(), bidiagonal decomposition requires M>=N", PZMath_errno.PZMath_EBADLEN); else if (tau_U.Size != A.ColumnCount) PZMath_errno.ERROR ("PZMath_linalg::BidiagDecomp(),size of tau_U must be N", PZMath_errno.PZMath_EBADLEN); else if (tau_V.Size + 1 != A.ColumnCount) PZMath_errno.ERROR ("PZMath_linalg::BidiagDecomp(),size of tau_V must be (N - 1)", PZMath_errno.PZMath_EBADLEN); else { int M = A.RowCount; int N = A.ColumnCount; int i; for (i = 0 ; i < N; i++) { /* Apply Householder transformation to current column */ { PZMath_vector c = A.Column(i); PZMath_vector v = c.SubVector(i, M - i); double tau_i = PZMath_linalg.HouseholderTransform(v); /* Apply the transformation to the remaining columns */ if (i + 1 < N) { PZMath_matrix m = A.Submatrix(i, i + 1, M - i, N - (i + 1)); PZMath_linalg.HouseholderHM(tau_i, v, m); } tau_U[i] = tau_i; } /* Apply Householder transformation to current row */ if (i + 1 < N) { PZMath_vector r = A.Row(i); PZMath_vector v = r.SubVector(i + 1, N - (i + 1)); double tau_i = PZMath_linalg.HouseholderTransform (v); /* Apply the transformation to the remaining rows */ if (i + 1 < M) { PZMath_matrix m = A.Submatrix(i+1, i+1, M - (i+1), N - (i+1)); PZMath_linalg.HouseholderMH(tau_i, v, m); } tau_V[i] = tau_i; } } } return PZMath_errno.PZMath_SUCCESS; }
public int Alloc(PZMath_multifit_fdfsolver_type T, int n, int p) { x = new PZMath_vector(p); f = new PZMath_vector(n); J = new PZMath_matrix(n, p); dx = new PZMath_vector(p); type = T; state = new lmder_state_t(); return (this.type.alloc) (this.state, n, p); }
// deep copy // reference copy is implemented by SubMatrix() public PZMath_matrix(PZMath_matrix m) { row = m.row; col = m.col; offset = m.offset; stride = m.stride; orgrow = m.orgrow; orgcol = m.orgcol; length = m.length; data = new double[length]; m.data.CopyTo(data, 0); }
/// <summary> /// N(mu, sigma) /// </summary> /// <param name="l">lower bound</param> /// <param name="u">upper bound</param> public MultivariateNormalDistribution(PZMath_vector m, PZMath_matrix s) { dimension = m.Size; mu = new PZMath_vector(dimension); mu.MemCopyFrom(m); sigma = new PZMath_matrix(dimension, dimension); sigma.MemCopyFrom(s); if (dimension != sigma.RowCount || dimension != sigma.ColumnCount) throw new ApplicationException("MultivariateNormalDistribution::MultivariateNormalDistribution(), mu and sigma in different dimension!"); Init(); }
/// <summary> /// sigma is a diagonal matrix /// </summary> /// <param name="m"></param> /// <param name="diag"></param> public MultivariateNormalDistribution(PZMath_vector m, PZMath_vector diag) { if (m.Size != diag.Size) throw new ApplicationException("MultivariateNormalDistribution::MultivariateNormalDistribution(), mu and sigma in different dimension!"); dimension = m.Size; mu = new PZMath_vector(dimension); mu.MemCopyFrom(m); sigma = new PZMath_matrix(dimension, dimension); for (int i = 0; i < dimension; i ++) sigma[i, i] = diag[i]; Init(); }
public static int BalanceColumns(PZMath_matrix A, PZMath_vector D) { int N = A.ColumnCount; int j; if (D.Size != N) { PZMath_errno.ERROR ("PZMath_linalg::BalanceColumns(), length of D must match second dimension of A", PZMath_errno.PZMath_EINVAL); } D.SetAll(1.0); for (j = 0; j < N; j++) { PZMath_vector A_j = A.Column(j); double s = PZMath_blas.Dasum (A_j); double f = 1.0; if (s == 0.0 || !PZMath_sys.Finite(s)) { D[j] = f; continue; } while (s > 1.0) { s /= 2.0; f *= 2.0; } while (s < 0.5) { s *= 2.0; f /= 2.0; } D[j] = f; if (f != 1.0) PZMath_blas.Dscal(1.0/f, A_j); } return PZMath_errno.PZMath_SUCCESS; }
/// <summary> /// kernel is a double template /// boolean AND operation for 1 and 0, /// don't care for 0.5 /// </summary> /// <param name="kernel"></param> /// <returns></returns> public PZMath_matrix AndTrueFalseDontCare2D(double[,] kernel) { // kernel information int hk = kernel.GetLength(1); int wk = kernel.GetLength(0); int halfHk = (hk - 1) / 2; int halfWk = (wk - 1) / 2; // matrix info int height = row; int width = col; PZMath_matrix expandSrcMatrix = this.BoundFillingBackgroundIntensityExpand(hk, wk, 255); bool[,] expandSrcBoolMatrix = expandSrcMatrix.ConvertToBoolMatrix(125); // prepare dst bool matrix int expandHeight = expandSrcBoolMatrix.GetLength(1); int expandWidth = expandSrcBoolMatrix.GetLength(0); bool[,] expandDstBoolMatrix = new bool[expandWidth, expandHeight]; int xStart = halfWk; int xEnd = width + halfWk; int yStart = halfHk; int yEnd = height + halfHk; for (int x = xStart; x < xEnd; x++) { for (int y = yStart; y < yEnd; y++) { bool isHit = true; // inside kernel for (int kx = -1 * halfWk; kx <= halfWk; kx++) { for (int ky = -1 * halfHk; ky <= halfHk; ky++) { // kernel is a double[,] // expandSrcBoolMatrix, and expandDstBoolMatrix are bool[,] if ((kernel[kx + halfWk, ky + halfHk] == 1 && !expandSrcBoolMatrix[x + kx, y + ky]) || (kernel[kx + halfWk, ky + halfHk] == 0 && expandSrcBoolMatrix[x + kx, y + ky])) { isHit = false; break; } } } expandDstBoolMatrix[x, y] = isHit; } } PZMath_matrix expandDstMatrix = new PZMath_matrix(expandDstBoolMatrix); PZMath_matrix dstMatrix = expandDstMatrix.BoundFillingBackgroundIntensityShrink(hk, wk); return dstMatrix; }
/// <summary> /// operator * example /// </summary> public static void OperatorMultiplyExample() { double[,] m1 = {{2, 3, 3, 5}, {6, 6, 8, 9}, {10, 11, 12, 13}}; double[,] m2 = {{2, 3, 3}, {6, 6, 8}, {10, 11, 12}, {14, 15, 17}}; PZMath_matrix matrix1 = new PZMath_matrix(m1); PZMath_matrix matrix2 = new PZMath_matrix(m2); // matrix multiply // correct answer // 122 132 151 // 254 277 315 // 388 423 483 PZMath_matrix newmatrix = matrix1 * matrix2; newmatrix.ScreenWriteLine(); }
/// <summary> /// LU decomposition and LU inverse example /// </summary> public static void LUExample() { double[,] m = {{2, 3, 3, 5}, {6, 6, 8, 9}, {10, 11, 12, 13}, {14, 15, 17, 17}}; PZMath_matrix matrix = new PZMath_matrix(m); matrix.ScreenWriteLine(); // LU decomposition // correct answer: // L = // 1.0000 0 0 0 // 0.1429 1.0000 0 0 // 0.4286 -0.5000 1.0000 0 // 0.7143 0.3333 -0.3333 1.0000 // U = // 14.0000 15.0000 17.0000 17.0000 // 0 0.8571 0.5714 2.5714 // 0 0 1.0000 3.0000 // 0 0 0 1.0000 // P = // 0 0 0 1 // 1 0 0 0 // 0 1 0 0 // 0 0 1 0 PZMath_permutation p = new PZMath_permutation(matrix.RowCount); PZMath_matrix LU = matrix.LUDecomp(p); LU.ScreenWriteLine(); // LU Invert // correct answer: // inv(m) = // -2.0833 0.6667 3.5000 -2.4167 // 1.0000 -1.0000 -1.0000 1.0000 // 1.0000 0 -3.0000 2.0000 // -0.1667 0.3333 1.0000 -0.8333 PZMath_matrix inverse = matrix.LUInvert(); inverse.ScreenWriteLine(); }
/// <summary> /// LU Det example /// </summary> public static void LUDetExample() { double[,] m = {{2, 3, 3, 5}, {6, 6, 8, 9}, {10, 11, 12, 13}, {14, 15, 17, 17}}; PZMath_matrix matrix = new PZMath_matrix(m); double det = matrix.LUDet(); // correct answer: // det(m) = -12 System.Console.WriteLine(det); }
/// <summary> /// Cholsky decomposition, A = L * L ^ T, return L (lower triangular matrix) /// </summary> /// <returns></returns> public PZMath_matrix CholeskyDecomp() { PZMath_matrix CD = new PZMath_matrix(this); PZMath_linalg.CholeskyDecomp(CD); // copy the lower triangle of CD to L PZMath_matrix L = new PZMath_matrix(row, col); for (int i = 0; i < row; i++) { for (int j = 0; j <= i; j++) { L[i, j] = CD[i, j]; } } return L; }
/// <summary> /// LU Invert /// </summary> /// <returns></returns> public PZMath_matrix LUInvert() { PZMath_permutation p = new PZMath_permutation(row); PZMath_matrix inverse = new PZMath_matrix(row, col); PZMath_matrix LU = this.LUDecomp(p); PZMath_linalg.LUInvert(LU, p, inverse); return inverse; }
/// <summary> /// kernel spatial convolution, mirror expand before convolution /// </summary> /// <param name="kernel"></param> /// <returns></returns> private PZMath_matrix Convolute2DMirrorExpand(PZMath_matrix kernel) { // kernel info int kernelHeight = kernel.RowCount; int kernelWidth = kernel.ColumnCount; int halfKernelHeight = (kernelHeight - 1) / 2; int halfKernelWidth = (kernelHeight - 1) / 2; // matrix info int height = row; int width = col; // expand src matrix PZMath_matrix expandSrc = this.BoundMirrorExpand(kernelHeight, kernelWidth); PZMath_matrix expandDst = new PZMath_matrix(expandSrc); // spatial convolute //int xStart = halfKernelWidth - 1; //int xEnd = width - halfKernelWidth; //int yStart = halfKernelHeight - 1; //int yEnd = height - halfKernelHeight; int xStart = halfKernelWidth; int xEnd = width + halfKernelWidth; int yStart = halfKernelHeight; int yEnd = height + halfKernelHeight; for (int x = xStart; x < xEnd; x++) { for (int y = yStart; y < yEnd; y++) { double localSum = 0.0; // inside kernel for (int kx = -1 * halfKernelWidth; kx <= halfKernelWidth; kx++) { for (int ky = -1 * halfKernelHeight; ky <= halfKernelHeight; ky++) { //localSum += expandSrc[y, x] * kernel[ky + halfKernelHeight, kx + halfKernelWidth]; localSum += expandSrc[y + ky, x + kx] * kernel[ky + halfKernelHeight, kx + halfKernelWidth]; } } expandDst[y, x] = localSum; } } // shrink dst matrix PZMath_matrix dstMatrix = expandDst.BoundMirrorShrink(kernelHeight, kernelWidth); return dstMatrix; }
/// <summary> /// x-direction convolute with an 1D double kernel /// mirror expand source matrix before convolution /// </summary> /// <param name="kernel">1D double kernel</param> /// <returns></returns> private PZMath_matrix ConvoluteRowMirrorExpand(PZMath_vector kernel) { // kernel info int kernelSize = kernel.Size; int halfKernelSize = (kernelSize - 1) / 2; // matrix info int height = row; int width = col; // expand src matrix PZMath_matrix expandSrc = this.BoundMirrorExpand(kernelSize, kernelSize); PZMath_matrix expandDst = new PZMath_matrix(expandSrc); // spatial convolute int xStart = halfKernelSize; int xEnd = width + halfKernelSize; int yStart = halfKernelSize; int yEnd = height + halfKernelSize; for (int x = xStart; x < xEnd; x++) { for (int y = yStart; y < yEnd; y++) { double localSum = 0.0; // inside kernel for (int k = -1 * halfKernelSize; k <= halfKernelSize; k ++) { localSum += expandSrc[y, x + k] * kernel[k + halfKernelSize]; } expandDst[y, x] = localSum; } } // shrink dst matrix PZMath_matrix dstMatrix = expandDst.BoundMirrorShrink(kernelSize, kernelSize); return dstMatrix; }
// sub matrix, starts from [offsetrow, offsetcolumn], with row = newrowcount; col = newcolumncount public PZMath_matrix Submatrix(int offsetrow, int offsetcol, int newrow,int newcol) { if (offsetrow < 0 || offsetrow + newrow > row || offsetcol< 0 || offsetcol + newcol > col) PZMath_errno.ERROR("Index Out Of Range", PZMath_errno.PZMath_EFAILED); PZMath_matrix m = new PZMath_matrix(); m.data = data; m.col = newcol; m.row = newrow; m.offset = offset + offsetrow * orgcol * stride + offsetcol * stride; m.stride = stride; m.orgcol = orgcol; m.orgrow = orgrow; m.length = length; return m; }
/// P. J. Burt, The pyramid as a structure for efficient computation , /// in A. Rosenfeld (ed), Multiresolution Image Processing and Analysis, Springer-Verlag, Berlin Heidelberg New York, 1984, pp 6 - 35 /// W.B. Goh and K.Y. Chan, "Shape description using gradient vector field histograms", /// in Scale Space Methods in Computer Vision, vol. 2695, Lecture Notes in Computer Science, L. D. Griffin and M. Lillholm, Eds.: Springer Berlin / Heidelberg, 2003, pp. 713-728. /// <summary> /// sub sampling, locally average by a kernel, l = 0, ..., N, N is top level, i.e. lowest resolution /// G_l(x, y) = sum(sum(w(m, n) * G_l-1(2x + m, 2y + n))), m, n, [-k, k] /// </summary> /// <param name="?"></param> /// <returns></returns> public PZMath_matrix Reduce(PZMath_matrix kernel) { return ReduceMirrorExpand(kernel); }
// m is the source matrix public void MemCopyFrom(PZMath_matrix m) { if (col != m.col || row != m.row) PZMath_errno.ERROR("PZMath_matrix::MemCopy(), Dest matrix is not equal to the source matrix.", PZMath_errno.PZMath_EFAILED); m.data.CopyTo(data, 0); }
/// <summary> ///Expand the matrix using mirror boundary condition /// /// for example /// /// A = [ /// 1 2 3 11 /// 4 5 6 12 /// 7 8 9 13 /// ] /// /// B = BoundMirrorExpand(A) will yield /// /// 5 4 5 6 12 6 /// 2 1 2 3 11 3 /// 5 4 5 6 12 6 /// 8 7 8 9 13 9 /// 5 4 5 6 12 6 /// /// Chenyang Xu and Jerry L. Prince, 9/9/1999 /// http://iacl.ece.jhu.edu/projects/gvf /// </summary> /// <param name="wk">kernal width</param> /// <param name="hk">kernal height</param> /// <returns></returns> public PZMath_matrix BoundMirrorExpand(int hk, int wk) { // half kernal width and height int halfWk = (wk - 1) / 2; int halfHk = (hk - 1) / 2; // original matrix height & width int height = this.RowCount; int width = this.ColumnCount; // expanded matrix height & width int heightA2 = height + 2 * halfHk; int widthA2 = width + 2 * halfWk; PZMath_matrix expand = new PZMath_matrix(heightA2, widthA2); int Wm1aHWK = width - 1 + halfWk; int HHKm1 = halfHk - 1; // upper row for (int xe = halfWk, x = 0; xe <= Wm1aHWK; xe++, x++) for (int ye = 0, y = halfHk; ye <= HHKm1; ye++, y--) expand[ye, xe] = this[y, x]; // bottom row int Hm1a2HHk = height - 1 + 2 * halfHk; for (int xe = halfWk, x = 0; xe <= Wm1aHWK; xe++, x++) for (int ye = height + halfHk, y = height - 2; ye <= Hm1a2HHk; ye++, y--) expand[ye, xe] = this[y, x]; // left column int HWKm1 = halfWk - 1; int Hm1aHHK = height - 1 + halfHk; for (int xe = 0, x = halfWk; xe <= HWKm1; xe++, x--) for (int ye = halfHk, y = 0; ye <= Hm1aHHK; ye++, y++) expand[ye, xe] = this[y, x]; // right column int Wm1a2HWK = width - 1 + 2 * halfWk; for (int xe = width + halfWk, x = width - 2; xe <= Wm1a2HWK; xe++, x--) for (int ye = halfHk, y = 0; ye <= Hm1aHHK; ye++, y++) expand[ye, xe] = this[y, x]; // center for (int xe = halfWk, x = 0; xe <= Wm1aHWK; xe++, x++) for (int ye = halfHk, y = 0; ye <= Hm1aHHK; ye++, y++) expand[ye, xe] = this[y, x]; // left-top corner for (int xc = 0, xe = 2 * halfWk; xc <= HWKm1; xc++, xe--) for (int y = 0; y <= HHKm1; y++) expand[y, xc] = expand[y, xe]; // right-top corner for (int xc = width + halfWk, xe = width + halfWk - 2; xc <= Wm1a2HWK; xc++, xe--) for (int y = 0; y <= HHKm1; y++) expand[y, xc] = expand[y, xe]; // left-bottom corner for (int xc = 0, xe = 2 * halfWk; xc <= HWKm1; xc++, xe--) for (int y = height + halfHk; y <= Hm1a2HHk; y++) expand[y, xc] = expand[y, xe]; // right-bottom corner for (int xc = width + halfWk, xe = width + halfWk - 2; xc <= Wm1a2HWK; xc++, xe--) for (int y = height + halfHk; y <= Hm1a2HHk; y++) expand[y, xc] = expand[y, xe]; return expand; }
public static void TestNonlinearLeastSquareFit() { PZMath_multifit_fdfsolver_type T = new PZMath_multifit_fdfsolver_type(); PZMath_multifit_fdfsolver s = new PZMath_multifit_fdfsolver(); int N = 40; int status; int i, iter = 0; int n = N; int p = 3; PZMath_matrix covar = new PZMath_matrix(p, p); double[] y = new double[N]; double[] sigma = new double[N]; double h = 1e-2; // step-size TestNonlinearLeastSquareFitParam d = new TestNonlinearLeastSquareFitParam(n, p, y, sigma, h); PZMath_multifit_function_fdf f = new PZMath_multifit_function_fdf(); double[] x_init = new double[3]; x_init[0] = 1.0; x_init[1] = 0.0; x_init[2] = 0.0; PZMath_vector x = new PZMath_vector(x_init); f.f = new multifit_delegate_f(TestPZMathMultifit.expb_f); f.df = new multifit_delegate_df(TestPZMathMultifit.expb_df); f.fdf = new multifit_delegate_fdf(TestPZMathMultifit.expb_fdf); f.n = n; f.p = p; f.parms = d; ParkMillerNormal r = new ParkMillerNormal(); // this is the data to be fiitted for (i = 0; i < n; i++) { double t = i; double tt = System.Math.Exp(-0.1 * t); d.y[i] = 1.0 + 5 * System.Math.Exp(-0.1 * t);// + r.NextVariate(); d.sigma[i] = 0.1; System.Diagnostics.Debug.WriteLine("data: " + i + " " + d.y[i] + " " + d.sigma[i]); } T.Init("PZMath_multifit_fdfsolver_lmsder"); s.Alloc(T, n, p); s.Init(f, x); s.PrintState(iter); do { iter++; status = s.Iterate(); System.Diagnostics.Debug.WriteLine("status = " + status); //printf ("status = %s \n", gsl_strerror(status)); s.PrintState(iter); if (status > 0) break; status = s.TestDelta(s.dx, s.x, 1e-4, 1e-4); } while (status == PZMath_errno.PZMath_CONTINUE && iter < 500); s.Covar(0.0, covar); covar.DebugWriteLine(); System.Console.WriteLine("A = " + s.FIT(0) + " +/- " + s.ERR(0, covar)); System.Console.WriteLine("lambda = " + s.FIT(1) + " +/- " + s.ERR(1, covar)); System.Console.WriteLine("b = " + s.FIT(2) + " +/- " + s.ERR(2, covar)); double chi = s.Chi(); System.Console.WriteLine("chisq/dof = " + (System.Math.Pow(chi, 2.0) / (double)(n - p))); System.Console.WriteLine("state = " + status); //printf ("status = %s \n", gsl_strerror(status)); }
/// <summary> /// sub sampling, locally average by a kernel, mirror expand before convolution /// </summary> /// <param name="kernel"></param> /// <returns></returns> private PZMath_matrix ReduceMirrorExpand(PZMath_matrix kernel) { // kernel info int kernelHeight = kernel.RowCount; int kernelWidth = kernel.ColumnCount; int halfKernelHeight = (kernelHeight - 1) / 2; int halfKernelWidth = (kernelHeight - 1) / 2; // matrix info int height = row; int width = col; int dstHeight = row / 2; int dstWidth = col / 2; // expand src matrix PZMath_matrix expandSrc = this.BoundMirrorExpand(kernelHeight, kernelWidth); PZMath_matrix dstMatrix = new PZMath_matrix(dstHeight, dstWidth); // local average (spatial convolute) int xOffset = halfKernelWidth; int yOffset = halfKernelHeight; for (int dstx = 0; dstx < dstWidth; dstx++) { for (int dsty = 0; dsty < dstHeight; dsty++) { double localSum = 0.0; // inside kernel for (int kx = -1 * halfKernelWidth; kx <= halfKernelWidth; kx++) { for (int ky = -1 * halfKernelHeight; ky <= halfKernelHeight; ky++) { int srcx = 2 * dstx + kx + xOffset; int srcy = 2 * dsty + ky + yOffset; int kernelx = kx + halfKernelWidth; int kernely = ky + halfKernelHeight; localSum += expandSrc[srcy, srcx] * kernel[kernely, kernelx]; } } dstMatrix[dsty, dstx] = localSum; } } return dstMatrix; }
/// <summary> /// determination from LU decomp /// </summary> /// <returns></returns> public double LUDet() { PZMath_permutation p = new PZMath_permutation(row); PZMath_matrix LU = new PZMath_matrix(this); int signum; PZMath_linalg.LUDecomp(LU, p, out signum); return PZMath_linalg.LUDet(LU, signum); }
/// <summary> /// kernel spatial convolution /// </summary> /// <param name="kernel"></param> /// <returns></returns> public PZMath_matrix Convolute2D(PZMath_matrix kernel) { return Convolute2DMirrorExpand(kernel); }
public static int expb_fdf(PZMath_vector x, object param, PZMath_vector f, PZMath_matrix J) { expb_f(x, param, f); expb_df(x, param, J); return PZMath_errno.PZMath_SUCCESS; }
/// <summary> /// operator * /// </summary> /// <param name="leftMatrix"></param> /// <param name="rightMatrix"></param> /// <returns></returns> public static PZMath_matrix operator *(PZMath_matrix leftMatrix, PZMath_matrix rightMatrix) { // matrix dimension valid check if (leftMatrix.ColumnCount != rightMatrix.RowCount) PZMath_errno.ERROR("PZMath_matrix::operator *, left matrix and right matrix are match in dimension."); int leftColumnCount = leftMatrix.ColumnCount; int leftRowCount = leftMatrix.RowCount; int rightColumnCount = rightMatrix.ColumnCount; int rightRowCount = rightMatrix.RowCount; int newRowCount = leftRowCount; int newColumnCount = rightColumnCount; PZMath_matrix newMatrix = new PZMath_matrix(newRowCount, newColumnCount); // multiply operation int newCol, newRow; for (newCol = 0; newCol < newColumnCount; newCol ++) { for (newRow = 0; newRow < newRowCount; newRow ++) { double temp = 0; for (int i = 0; i < leftColumnCount; i ++) temp += leftMatrix[newRow, i] * rightMatrix[i, newCol]; newMatrix[newRow, newCol] = temp; } } return newMatrix; }
// These functions compute the matrix-vector product and sum // y = \alpha op(A) x + \beta y, // where op(A) = A, A^T, A^H for method = // 0 - CblasNoTrans, // 1 - CblasTrans public static int Dgemv(int method, double alpha, PZMath_matrix A, PZMath_vector X, double beta, PZMath_vector Y) { int M = A.RowCount; int N = A.ColumnCount; if ((method == 0 && N == X.Size && M == Y.Size) || (method == 1 && M == X.Size && N == Y.Size)) { if (method == 0) // no trans { for (int i = 0; i < M; i ++) // each element of Y { double temp = 0; for (int j = 0; j < N; j ++) // each element of A temp += A[i, j] * X[j]; Y[i] = alpha * temp + beta * Y[i]; } } else // trans { for (int i = 0; i < N; i ++) // each element of Y { double temp = 0; for (int j = 0; j < M; j ++) // each element of A temp += A[j, i] * X[j]; Y[i] = alpha * temp + beta * Y[i]; } } return PZMath_errno.PZMath_SUCCESS; } else { PZMath_errno.ERROR ("PZMath_blas::Dgemv(), invalid length", PZMath_errno.PZMath_EBADLEN); return 0; } }
// fit data from y = exp(x), x :[0 : 2] public static void TestLinearLeastSquareFit() { int i, n; n = 19; // -- prepare model parameters double xi, yi, chisq; PZMath_matrix X, cov; PZMath_vector y, w, c; X = new PZMath_matrix(n, 3); y = new PZMath_vector(n); w = new PZMath_vector(n); c = new PZMath_vector(3); cov = new PZMath_matrix(3, 3); // -- data to be fitted //PZMath_random_ParkMiller_Normal r = new PZMath_random_ParkMiller_Normal(); for (i = 0; i < n; i++) { xi = 0.1 + 0.1 * i; yi = System.Math.Exp(xi); // f(x) System.Console.WriteLine(xi + " " + yi); X[i, 0] = 1.0; X[i, 1] = xi; X[i, 2] = xi * xi; y[i] = yi; w[i] = 1.0; } PZMath_multifit_linear l = new PZMath_multifit_linear(); l.Alloc(n, 3); l.Wlinear(X, w, y, c, cov, out chisq); System.Console.WriteLine("# best fit: Y = " + c[0] + " + " + c[1] + " X + " + c[2] + " X ^ 2"); System.Console.WriteLine("# covariance matrix:"); cov.ScreenWriteLine(); System.Console.WriteLine("# chisq = " + chisq); }
/// <summary> /// Cholsky decomposition example /// </summary> public static void CholeskyDecompExample() { double[,] m = {{1, 1, 1, 1, 1}, {1, 2, 3, 4, 5}, {1, 3, 6, 10, 15}, {1, 4, 10, 20, 35}, {1, 5, 15, 35, 70}}; PZMath_matrix matrix = new PZMath_matrix(m); PZMath_matrix L = matrix.CholeskyDecomp(); // correct answer: // L = // 1 0 0 0 0 // 1 1 0 0 0 // 1 2 1 0 0 // 1 3 3 1 0 // 1 4 6 4 1 L.ScreenWriteLine(); }
public static int Dtrsv(CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, PZMath_matrix A, PZMath_vector x) { int M = A.RowCount; int N = A.ColumnCount; if (M != N) { PZMath_errno.ERROR("PZMath_blas::Dtrsv(), matrix must be square", PZMath_errno.PZMath_ENOTSQR); } else if (N != x.Size) { PZMath_errno.ERROR("PZMath_blas::Dtrsv(), invalid length", PZMath_errno.PZMath_EBADLEN); } bool nonunit = (Diag == CBLAS_DIAG.CblasNonUnit); int ix, jx; int i, j; CBLAS_TRANSPOSE Trans = (TransA != CBLAS_TRANSPOSE.CblasConjTrans) ? TransA : CBLAS_TRANSPOSE.CblasTrans; CBLAS_ORDER order = CBLAS_ORDER.CblasRowMajor; if (N == 0) return PZMath_errno.PZMath_SUCCESS; /* form x := inv( A )*x */ if ((order == CBLAS_ORDER.CblasRowMajor && Trans == CBLAS_TRANSPOSE.CblasNoTrans && Uplo == CBLAS_UPLO.CblasUpper) || (order == CBLAS_ORDER.CblasColMajor && Trans == CBLAS_TRANSPOSE.CblasTrans && Uplo == CBLAS_UPLO.CblasLower)) { /* backsubstitution */ ix = N - 1; if (nonunit) x[ix] = x[ix] / A[N - 1, N - 1]; ix--; for (i = N - 1; i > 0 && (i-- > 0); ) { double tmp = x[ix]; jx = ix + 1; for (j = i + 1; j < N; j++) { double Aij = A[i, j]; tmp -= Aij * x[jx]; jx++; } if (nonunit) { x[ix] = tmp / A[i, i]; } else { x[ix] = tmp; } ix--; } } else if ((order == CBLAS_ORDER.CblasRowMajor && Trans == CBLAS_TRANSPOSE.CblasNoTrans && Uplo == CBLAS_UPLO.CblasLower) || (order == CBLAS_ORDER.CblasColMajor && Trans == CBLAS_TRANSPOSE.CblasTrans && Uplo == CBLAS_UPLO.CblasUpper)) { /* forward substitution */ ix = 0; if (nonunit) { x[ix] = x[ix] / A[0, 0]; } ix++; for (i = 1; i < N; i++) { double tmp = x[ix]; jx = 0; for (j = 0; j < i; j++) { double Aij = A[i, j]; tmp -= Aij * x[jx]; jx++; } if (nonunit) { x[ix] = tmp / A[i, i]; } else { x[ix] = tmp; } ix++; } } else if ((order == CBLAS_ORDER.CblasRowMajor && Trans == CBLAS_TRANSPOSE.CblasTrans && Uplo == CBLAS_UPLO.CblasUpper) || (order == CBLAS_ORDER.CblasColMajor && Trans == CBLAS_TRANSPOSE.CblasNoTrans && Uplo == CBLAS_UPLO.CblasLower)) { /* form x := inv( A' )*x */ /* forward substitution */ ix = 0; if (nonunit) { x[ix] = x[ix] / A[0, 0]; } ix++; for (i = 1; i < N; i++) { double tmp = x[ix]; jx = 0; for (j = 0; j < i; j++) { double Aji = A[j, i]; tmp -= Aji * x[jx]; jx++; } if (nonunit) { x[ix] = tmp / A[i, i]; } else { x[ix] = tmp; } ix++; } } else if ((order == CBLAS_ORDER.CblasRowMajor && Trans == CBLAS_TRANSPOSE.CblasTrans && Uplo == CBLAS_UPLO.CblasLower) || (order == CBLAS_ORDER.CblasColMajor && Trans == CBLAS_TRANSPOSE.CblasNoTrans && Uplo == CBLAS_UPLO.CblasUpper)) { /* backsubstitution */ ix = N - 1; if (nonunit) { x[ix] = x[ix] / A[(N - 1), (N - 1)]; } ix--; for (i = N - 1; i > 0 && (i-- > 0); ) { double tmp = x[ix]; jx = ix + 1; for (j = i + 1; j < N; j++) { double Aji = A[j, i]; tmp -= Aji * x[jx]; jx++; } if (nonunit) { x[ix] = tmp / A[i, i]; } else { x[ix] = tmp; } ix--; } } else { PZMath_errno.ERROR("PZMath_blas::Dtrsv(), unrecognized operation"); } return PZMath_errno.PZMath_SUCCESS; }
public static void IOExample() { double[,] m = {{2, 3, 3, 5}, {6, 6, 8, 9}, {10, 11, 12, 13}, {14, 15, 17, 17}}; PZMath_matrix matrix = new PZMath_matrix(m); matrix.WriteFile("matrix.txt"); PZMath_matrix readMatrix = new PZMath_matrix(); readMatrix.ReadFile("matrix.txt"); readMatrix.ScreenWriteLine(); }