/// <summary> /// Constructs a multivariate polynomial of a given rank and spatial dimensionality. /// </summary> /// <param name="nDims"><see cref="Poly.Ndims"/>.</param> /// <param name="rank"><see cref="Poly.Rank"/>.</param> public Poly(int nDims, int rank) { if (nDims < 1) { throw new ArgumentException("The number of spatial dimensions must be at least 1."); } if (rank < 1) { throw new ArgumentException("The polynomial rank must be at least 1."); } this.Ndims = nDims; this.Rank = rank; // How many polynomial coefficients total? this.Ncoeffs = Poly.Ncoeff(nDims, rank); // Allocate coefficients. this.Coeffs = new int[this.Ncoeffs, nDims]; // One coefficient (or row) at a time. int[] row = new int[nDims]; for (int i = 0; i < row.Length; i++) { row[i] = -1; } // For each coefficient. for (int iCoeff = 0; iCoeff < this.Ncoeffs; iCoeff++) { int i, j; // Increment the smallest digit and begin to handle "carry-over" arithmetic. i = -1; while (++row[++i] == nDims) { ; // When a digit is maxed, keep incrementing rightward until we're not maxed out. } // Finish the "carry-over" by ensuring that any leftward maxed digits have been reset. for (j = i - 1; j >= 0; j--) { if (row[j] == nDims) { row[j] = row[j + 1]; } } // Copy last row to output for (j = 0; j < nDims; j++) { this.Coeffs[iCoeff, j] = row[j]; } } }
/// <summary> /// Initializes an untrained instance of the <see cref="Morpe.Classifier"/> class. The classifier should be trained /// (see <see cref="Train"/>) before it can be used for classification. /// </summary> /// <param name="nCats"><see cref="Ncats"/></param> /// <param name="nDims"><see cref="Ndims"/></param> /// <param name="rank"><see cref="Rank"/></param> public Classifier(int nCats, int nDims, int rank) { this.Ncats = nCats; this.Ndims = nDims; this.Coeffs = new Poly(nDims, rank); this.Npoly = 1; if (this.Ncats > 2) { this.Npoly = this.Ncats; } this.Params = Static.NewArrays <float>(this.Npoly, this.Coeffs.Ncoeffs); this.Quant = new Quantization[this.Npoly]; }
/// <summary> /// Computes the polynomial expansion in place. You can undo the expansion by calling <see cref="Contract"/> /// </summary> /// <param name="poly">The defiinition of the polynomial expansion.</param> public void Expand(Poly poly) { for (int iCat = 0; iCat < this.Ncats; iCat++) { int nSamp = this.Neach[iCat]; for (int iSamp = 0; iSamp < nSamp; iSamp++) { float[] x = this.X[iCat][iSamp]; if (x.Length > this.Ndims) { this.X[iCat][iSamp] = poly.Expand(Static.GetSubarray(x, 0, this.Ndims - 1)); } else { this.X[iCat][iSamp] = poly.Expand(x); } } } }
/// <summary> /// This is used by <see cref="GetDual"/> and <see cref="GetDuals"/>. /// </summary> /// <param name="toCopy">A classifier having more than 1 polynomial.</param> /// <param name="targetPoly">The target polynomial function.</param> protected Classifier(Classifier toCopy, int targetPoly) { this.Ncats = 2; this.Ndims = toCopy.Ndims; this.Coeffs = new Poly(this.Ndims, toCopy.Coeffs.Rank); this.Npoly = 1; this.Params = Static.NewArrays <float>(this.Npoly, this.Coeffs.Ncoeffs); Array.Copy(toCopy.Params[targetPoly], this.Params[0], this.Coeffs.Ncoeffs); this.Quant = new Quantization[this.Npoly]; Quantization q; q = toCopy.Quant[targetPoly]; if (q != null) { this.Quant[0] = q.Copy(); } }
protected Classifier(Classifier toCopy) { this.Ncats = toCopy.Ncats; this.Ndims = toCopy.Ndims; this.Coeffs = new Poly(this.Ndims, toCopy.Coeffs.Rank); this.Npoly = 1; if (this.Ncats > 2) { this.Npoly = this.Ncats; } this.Params = Static.Copy <float>(toCopy.Params); this.Quant = new Quantization[this.Npoly]; Quantization q; for (int i = 0; i < this.Npoly; i++) { q = toCopy.Quant[i]; if (q != null) { this.Quant[i] = q.Copy(); } } }