public void StandardTest() { // dimension is not positive { ArgumentExceptionAssert.Throw( () => { var basis = Basis.Standard(0); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_POSITIVE"), expectedParameterName: "dimension"); } // dimension is valid { var basis = Basis.Standard(2); var actual = basis.GetBasisMatrix(); var expected = DoubleMatrix.Identity(2); DoubleMatrixAssert.AreEqual( expected, actual, DoubleMatrixTest.Accuracy); } }
/// <summary> /// Tests that the /// <see cref="PrincipalProjections.RegressSupplementaryVariables"/> /// method fails when supplementaryVariables has not /// the expected number of rows. public static void SupplementaryVariablesHasWrongNumberOfRows( TestablePrincipalProjections testablePrincipalProjections) { var principalProjections = testablePrincipalProjections.PrincipalProjections; var STR_EXCEPT_GDA_ROWS_NOT_EQUAL_TO_ACTIVE_POINTS = ImplementationServices.GetResourceString( "STR_EXCEPT_GDA_ROWS_NOT_EQUAL_TO_ACTIVE_POINTS"); string parameterName = "supplementaryVariables"; DoubleMatrix supplementaryVariables = DoubleMatrix.Dense( principalProjections.ActiveCloud.Coordinates.NumberOfRows + 1, 2); ArgumentExceptionAssert.Throw( () => { principalProjections.RegressSupplementaryVariables( supplementaryVariables); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: STR_EXCEPT_GDA_ROWS_NOT_EQUAL_TO_ACTIVE_POINTS, expectedParameterName: parameterName); }
/// <summary> /// Provides methods to test that the /// <see cref="NumericalBlock. /// GetNumericalBlocks(DoubleMatrix, DoubleMatrix)"/> /// method fails when numerical and target data /// have different lengths. public static void NumericalAndTargetDataHaveDifferentLengths() { var numericalData = DoubleMatrix.Dense(5, 1, new double[5] { -1, -1, -1, 1, 1 }); var targetData = DoubleMatrix.Dense(4, 1, new double[4] { 20, 10, 10, 10 }); ArgumentExceptionAssert.Throw( () => { var blocks = NumericalBlock.GetNumericalBlocks( numericalData, targetData); }, expectedType: typeof(ArgumentException), expectedPartialMessage: string.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_HAVE_SAME_COUNT"), nameof(numericalData)), expectedParameterName: "targetData"); }
internal static void ValidateSampleInput( int sampleSize, int[] destinationArray, int destinationIndex) { ProbabilityDistribution.ValidateSampleInput(sampleSize); if (destinationArray is null) { throw new ArgumentNullException(nameof(destinationArray)); } if (destinationIndex < 0) { throw new ArgumentOutOfRangeException(nameof(destinationIndex), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_NON_NEGATIVE")); } int length = destinationArray.Length; if (sampleSize > (length - destinationIndex)) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, ImplementationServices.GetResourceString( "STR_EXCEPT_PDF_SAMPLESIZE_ARRAYLENGTH_MISMATCH"), nameof(sampleSize), nameof(destinationArray), nameof(destinationIndex)), nameof(sampleSize)); } }
public void AnalyzeTest() { // dataSet is null { string parameterName = "dataSet"; ArgumentExceptionAssert.Throw( () => { MultipleCorrespondence.Analyze( null); }, expectedType: typeof(ArgumentNullException), expectedPartialMessage: ArgumentExceptionAssert.NullPartialMessage, expectedParameterName: parameterName); } // dataSet must have positive marginal column sums { var STR_EXCEPT_GDA_MCA_NON_POSITIVE_MARGINAL_SUMS = ImplementationServices.GetResourceString( "STR_EXCEPT_GDA_MCA_NON_POSITIVE_MARGINAL_SUMS"); string parameterName = "dataSet"; CategoricalVariable color = new("COLOR") { { 0, "Red" },
/// <summary> /// Analyzes the multiple correspondence of the specified /// categorical data set. /// </summary> /// <param name="dataSet">The data set to analyze.</param> /// <returns>The multiple correspondence of the specified data set.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="dataSet"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// The disjoint form of parameter <paramref name="dataSet"/> has at least a non /// positive marginal sum. /// </exception> /// <exception cref="InvalidOperationException"> /// The Singular Value Decomposition needed to acquire /// the correspondence cannot be executed or does not converge.<br/> /// -or-<br/> /// No principal variable has positive variance. /// The principal information cannot be acquired. /// </exception> public static MultipleCorrespondence Analyze( CategoricalDataSet dataSet) { if (dataSet is null) { throw new ArgumentNullException(nameof(dataSet)); } var disjunctiveProtocol = dataSet.Disjoin(); Correspondence correspondence; try { correspondence = Correspondence.Analyze( disjunctiveProtocol); } catch (ArgumentOutOfRangeException) { throw new ArgumentOutOfRangeException(nameof(dataSet), ImplementationServices.GetResourceString( "STR_EXCEPT_GDA_MCA_NON_POSITIVE_MARGINAL_SUMS")); } catch (Exception) { throw; } var multipleCorrespondence = new MultipleCorrespondence { correspondence = correspondence }; return(multipleCorrespondence); }
/// <summary> /// Gets the indexes in the <see cref="IndexCollection" /> corresponding to /// the specified positions. /// </summary> /// <param name="positions">The positions of the indexes to get.</param> /// <value>The collection of indexes at the specified positions.</value> /// <exception cref="ArgumentNullException"> /// <paramref name="positions"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="positions"/> contains a value which is negative or greater than or equal to /// <see cref="Count"/>. /// </exception> public IndexCollection this[IndexCollection positions] { get { if (null == positions) { throw new ArgumentNullException(nameof(positions)); } int numberOfIndexes = this.indexes.Length; if (positions.maxIndex >= numberOfIndexes) { throw new ArgumentOutOfRangeException(nameof(positions), ImplementationServices.GetResourceString( "STR_EXCEPT_IND_POSITION_EXCEEDS_DIMS")); } int[] subIndexes = new int[positions.Count]; for (int i = 0; i < positions.Count; i++) { subIndexes[i] = this.indexes[positions[i]]; } return(new IndexCollection(subIndexes, false)); } }
/// <summary> /// Returns the norm of the vector having the specified coordinates. /// </summary> /// <param name="coordinates">The vector coordinates.</param> /// <returns> /// The norm of the vector having the specified coordinates.</returns> /// <remarks> /// <para> /// Parameter <paramref name="coordinates"/> must be passed as /// a row vector. /// Let <latex>A</latex> be the /// <see cref="GetBasisMatrix">matrix representation</see> /// of this instance, and let <latex>\bc{A}{x}</latex> be /// equal to <paramref name="coordinates"/>. Then /// method <see cref="Norm(DoubleMatrix)"/> /// returns /// <latex mode="display"> /// \bnorm{A}{x} = \bsprod{A}{x|x}^{1/2}, /// </latex> /// where <latex>\bsprod{A}{\cdot|\cdot}</latex> is the /// <see cref="ScalarProduct(DoubleMatrix, DoubleMatrix)"> /// scalar product</see> induced by /// basis <latex>\A</latex>. /// </para> /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="coordinates"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="coordinates"/> is not a row vector.<br/> /// -or-<br/> /// <paramref name="coordinates"/> has <see cref="DoubleMatrix.Count"/> /// not equal to the <see cref="Dimension"/> of /// the <see cref="Basis"/>. /// </exception> public double Norm(DoubleMatrix coordinates) { #region Input validation if (coordinates is null) { throw new ArgumentNullException(nameof(coordinates)); } if (!coordinates.IsRowVector) { throw new ArgumentOutOfRangeException( nameof(coordinates), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_ROW_VECTOR")); } int k = this.Dimension; if (coordinates.Count != k) { throw new ArgumentOutOfRangeException( nameof(coordinates), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_BASIS_COMPLIANT_VECTOR")); } #endregion var q = this.basisScalarProducts; return((double)(coordinates * q * coordinates.Transpose())); }
/// <summary> /// Gets or sets the entry of the <see cref="DoubleMatrixRow"/> /// having the specified column index. /// </summary> /// <value>The row entry corresponding to the specified /// column index.</value> /// <remarks> /// <inheritdoc cref="DoubleMatrixRow" /// path="para[@id='row.in.collection']"/> /// <para> /// If setting, the <see cref="this[string]"/> indexer fires the /// <see cref="PropertyChanged"/> event /// notifying that the name of the changed property is <c>"[" + j + ]"</c>, /// where <c>j</c> is <paramref name="columnIndex"/>, /// and the new value becomes /// the entry of <see cref="DoubleMatrixRowCollection.Matrix"/> having row and column /// indexes given /// by <see cref="Index"/> and <paramref name="columnIndex"/>, /// respectively. /// </para> /// <para> /// If <paramref name="columnIndex"/> represents any value returned by /// <see cref="DoubleMatrixRowCollection.XDataColumn"/>, /// <see cref="DoubleMatrixRowCollection.YDataColumn"/>, or /// <see cref="DoubleMatrixRowCollection.ZDataColumn"/>, then the /// <see cref="PropertyChanged"/> event is also fired to /// notify that properties <see cref="XData"/>, <see cref="YData"/>, or /// <see cref="ZData"/> have changed values, respectively. /// </para> /// </remarks> /// <exception cref="ArgumentException"> /// <paramref name="columnIndex"/> does not represent a valid integer value. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="columnIndex"/> does not represent a valid column index /// for the matrix from /// which this row has been collected. /// </exception> /// <seealso cref="XData"/> /// <seealso cref="YData"/> /// <seealso cref="ZData"/> public double this[string columnIndex] { get { if (!Int32.TryParse(columnIndex, out int index)) { throw new ArgumentException( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_CANNOT_PARSE_AS_INT32"), nameof(columnIndex)); } return(this[index]); } set { if (!Int32.TryParse(columnIndex, out int index)) { throw new ArgumentException( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_CANNOT_PARSE_AS_INT32"), nameof(columnIndex)); } this[index] = value; } }
/// <summary> /// Throws if a basis matrix is singular. /// </summary> /// <param name="basisMatrix">The basis matrix.</param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="basisMatrix"/> is singular. /// </exception> private static void ThrowIfBasisMatrixIsSingular( DoubleMatrix basisMatrix) { double[] basisArray = basisMatrix.AsColumnMajorDenseArray(); int k = basisMatrix.NumberOfColumns; int[] ipiv = new int[k]; int lapackInfo; lapackInfo = SafeNativeMethods.LAPACK.DGETRF( SafeNativeMethods.LAPACK.ORDER.ColMajor, k, k, basisArray, k, ipiv); if (0 < lapackInfo) { throw new ArgumentOutOfRangeException( nameof(basisMatrix), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_NON_SINGULAR")); } }
/// <summary> /// Computes the natural logarithm of the Gamma function. /// </summary> /// <param name="x"> /// The argument at which the function must be evaluated. /// </param> /// <returns> /// The value taken on by the function. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="x"/> is not positive. /// </exception> /// <seealso href="https://en.wikipedia.org/wiki/Gamma_function#The_log-gamma_function"/> public static double LogGamma(double x) { if (x <= 0.0) { throw new ArgumentOutOfRangeException( nameof(x), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_POSITIVE")); } // This is based on Lanczos, C., 1964, // SIAM Journal on Numerical Analysis, Series B, // Vol. 1, pp. 86-96. // // Sketch of the methodology: // Approximate log(T(x+1)), hence subtract log(x) // so exploiting the relation T(x+1) = x*T(x). double[] c = SpecialFunctions._GammaLanczosCoefficients; double t = x + 5.5; double series = 1.000000000190015; // first coefficient for (int j = 0; j < c.Length; j++) { series += c[j] / (x + j + 1); } return(-t + (x + 0.5) * Math.Log(t) + Math.Log(_SqrtPiBy2 * series / x)); }
/// <summary> /// Computes the Factorial function of the /// specified integer. /// </summary> /// <param name="n"> /// The argument at which the function must be evaluated. /// </param> /// <returns> /// The value taken on by the function. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="n"/> is negative. /// </exception> /// <seealso href="https://en.wikipedia.org/wiki/Factorial"/> public static double Factorial(int n) { if (n < 0.0) { throw new ArgumentOutOfRangeException( nameof(n), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_NON_NEGATIVE")); } // Returns exact values for n <= 170, // 170! being the largest factorial whose floating-point // approximation can be represented as a 64-bit IEEE 754 // floating -point value. if (n <= 170) { double f = 1.0; int i = 2; while (i <= n) { f *= i++; } return(f); } // Otherwise, return +Inf return(Double.PositiveInfinity); }
public double Gaussian( double mu, double sigma) { if (sigma <= 0) { throw new ArgumentOutOfRangeException(nameof(sigma), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_POSITIVE")); } double sample; unsafe { SafeNativeMethods.VSL.vdRngGaussian( 0, this.descriptor.DangerousGetHandle().ToPointer(), 1, &sample, mu, sigma); } return(sample); }
/// <summary> /// Computes the Singular Value Decomposition of the /// specified matrix. /// </summary> /// <param name="matrix">The matrix to decompose.</param> /// <param name="leftSingularVectors"> /// The matrix whose columns represent the left singular vectors. /// </param> /// <param name="conjugateTransposedRightSingularVectors"> /// The matrix whose rows represent the conjugate transposed right /// singular vectors. /// </param> /// <returns> /// The diagonal matrix of singular values. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="matrix"/> is <b>null</b>. /// </exception> public static DoubleMatrix Decompose( DoubleMatrix matrix, out DoubleMatrix leftSingularVectors, out DoubleMatrix conjugateTransposedRightSingularVectors) { #region Input validation if (matrix is null) { throw new ArgumentNullException(nameof(matrix)); } #endregion int m = matrix.NumberOfRows; int n = matrix.NumberOfColumns; int min_m_n = m < n ? m : n; double[] a = matrix.AsColumnMajorDenseArray(); double[] s = new double[min_m_n]; double[] u = new double[m * m]; double[] vt = new double[n * n]; int lapackInfo; double[] superb = new double[min_m_n - 1]; lapackInfo = SafeNativeMethods.LAPACK.DGESVD( matrix_layout: SafeNativeMethods.LAPACK.ORDER.ColMajor, jobu: 'A', jobvt: 'A', m, n, a, lda: m, s: s, u, ldu: m, vt, ldvt: n, superb); if (lapackInfo > 0) { throw new InvalidOperationException( ImplementationServices.GetResourceString( "STR_EXCEPT_ALG_DOES_NOT_CONVERGE")); } DoubleMatrix values = DoubleMatrix.Sparse(m, n, min_m_n); for (int i = 0; i < min_m_n; i++) { values[i, i] = s[i]; } leftSingularVectors = DoubleMatrix.Dense(m, m, u, copyData: false); conjugateTransposedRightSingularVectors = DoubleMatrix.Dense(n, n, vt, copyData: false); return(values); }
/// <summary> /// Computes the variances of the specified supplementary variables. /// </summary> /// <param name="supplementaryVariables"> /// The supplementary variables. /// </param> /// <remarks> /// <para><b>Points and variables</b></para> /// <para> /// The coordinates of a given point /// have length equal to the dimension of the cloud basis. /// The collection of the coordinates of all points on a given axis /// is referred to as an <i>active variable</i>, as opposed to /// <i>supplementary</i> ones. /// The matrix passed as <paramref name="supplementaryVariables"/> /// must have as many rows as the number of points in the cloud, while /// the number of columns is the number of supplementary variables. /// </para> /// </remarks> /// <returns> /// The supplementary variances as a row vector. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="supplementaryVariables"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// The number of rows in <paramref name="supplementaryVariables"/> is /// not equal to the number of points in the cloud. /// </exception> public DoubleMatrix GetVariances(DoubleMatrix supplementaryVariables) { if (supplementaryVariables is null) { throw new ArgumentNullException(nameof(supplementaryVariables)); } int numberOfVariables = supplementaryVariables.NumberOfRows; if (this.coordinates.NumberOfRows != numberOfVariables) { throw new ArgumentOutOfRangeException( nameof(supplementaryVariables), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_ROW_DIM_MUST_MATCH_INDIVIDUALS_COUNT")); } var w_s_t = this.weights.Transpose(); var squaredCoordinates = DoubleMatrix.ElementWiseMultiply( supplementaryVariables, supplementaryVariables); var meanCoordinates = w_s_t * supplementaryVariables; var squaredMeanCoordinates = DoubleMatrix.ElementWiseMultiply( meanCoordinates, meanCoordinates); return(w_s_t * squaredCoordinates - squaredMeanCoordinates); }
/// <summary> /// Tests that the /// <see cref="PrincipalProjections.LocateSupplementaryPoints"/> /// method fails when activeCoordinates has not /// the expected number of columns. public static void ActiveCoordinatesHasWrongNumberOfColumns( TestablePrincipalProjections testablePrincipalProjections) { var principalProjections = testablePrincipalProjections.PrincipalProjections; var STR_EXCEPT_GDA_COLUMNS_NOT_EQUAL_TO_ACTIVE_VARIABLES = ImplementationServices.GetResourceString( "STR_EXCEPT_GDA_COLUMNS_NOT_EQUAL_TO_ACTIVE_VARIABLES"); string parameterName = "activeCoordinates"; DoubleMatrix activeCoordinates = DoubleMatrix.Dense( 2, principalProjections.ActiveCloud.Coordinates.NumberOfColumns + 1); ArgumentExceptionAssert.Throw( () => { principalProjections.LocateSupplementaryPoints( activeCoordinates); }, expectedType: typeof(ArgumentOutOfRangeException), expectedPartialMessage: STR_EXCEPT_GDA_COLUMNS_NOT_EQUAL_TO_ACTIVE_VARIABLES, expectedParameterName: parameterName); }
public void Gaussian( int sampleSize, double[] destinationArray, int destinationIndex, double mu, double sigma) { ProbabilityDistribution.ValidateSampleInput( sampleSize, destinationArray, destinationIndex); if (sigma <= 0) { throw new ArgumentOutOfRangeException(nameof(sigma), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_POSITIVE")); } unsafe { fixed(double *destinationPointer = &destinationArray[destinationIndex]) { SafeNativeMethods.VSL.vdRngGaussian( 0, this.descriptor.DangerousGetHandle().ToPointer(), sampleSize, destinationPointer, mu, sigma); } } }
/// <summary> /// Returns a <see cref="Cloud"/> representing the same points /// of this instance, using coordinates referred to the /// specified basis. /// </summary> /// <remarks> /// <para> /// The point coordinates are updated to be referable /// to the new basis. /// </para> /// </remarks> /// <returns> /// A <see cref="Cloud"/> representing the same points /// of this instance, using coordinates referred to the /// specified basis.</returns> /// <param name="newBasis">The new basis.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="newBasis" /> is <b>null</b>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="newBasis" /> has a <see cref="Basis.Dimension"/> /// not equal to that of the current one. /// </exception> public Cloud Rebase(Basis newBasis) { #region Input validation if (newBasis is null) { throw new ArgumentNullException(nameof(newBasis)); } int k = this.Basis.Dimension; if (newBasis.Dimension != k) { throw new ArgumentOutOfRangeException( nameof(newBasis), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_BASES_MUST_SHARE_DIMENSION")); } #endregion var a = this.Basis; var b = newBasis; var x_sa = this.coordinates; var x_sb = Basis.ChangeCoordinates( newBasis: b, currentCoordinates: x_sa, currentBasis: a); return(new Cloud( coordinates: x_sb, weights: this.weights.Clone(), basis: b, copyData: false)); }
/// <summary> /// Initializes a new instance of the <see cref="Basis"/> class. /// </summary> /// <param name="basisMatrix">The matrix representation of the basis. /// </param> /// <remarks> /// <para> /// In a finite vector space having dimension <latex>K</latex>, a basis, /// say <latex>\A</latex>, /// is a collection of <latex>K</latex> linearly independent vectors /// <latex>\alpha_1,\dots,\alpha_K</latex>. Each basis can /// be represented by a matrix whose columns are given by the vectors /// in the basis: /// <latex mode="display"> /// A = \mx{ \alpha_1 & \cdots &\alpha_K}. /// </latex> /// Given a matrix representation <latex>A</latex>, a /// corresponding <see cref="Basis"/> instance /// can be created by passing <latex>A</latex> as /// parameter <paramref name="basisMatrix"/>. /// </para> /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="basisMatrix"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="basisMatrix"/> is not square.<br/> /// -or-<br/> /// <paramref name="basisMatrix"/> is singular. /// </exception> public Basis(DoubleMatrix basisMatrix) { #region Input validation if (basisMatrix is null) { throw new ArgumentNullException( nameof(basisMatrix)); } if (!basisMatrix.IsSquare) { throw new ArgumentOutOfRangeException( nameof(basisMatrix), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_SQUARE")); } Basis.ThrowIfBasisMatrixIsSingular(basisMatrix); #endregion this.basisMatrixT = basisMatrix.Transpose(); this.basisScalarProducts = this.basisMatrixT * basisMatrix; }
/// <summary> /// Computes the Binomial coefficient of the specified /// pair of integers. /// </summary> /// <param name="n"> /// The number of available items. /// </param> /// <param name="k"> /// The number of items to be taken at a time. /// </param> /// <remarks> /// This is the number of combinations /// of <paramref name="n"/> items taken /// <paramref name="k"/> at a time. /// </remarks> /// <returns> /// The value taken on by the Binomial coefficient. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="n"/> is negative.<br/> /// -or-<br/> /// <paramref name="k"/> is negative.<br/> /// -or-<br/> /// <paramref name="k"/> is greater than /// <paramref name="n"/>. /// </exception> /// <seealso href="https://en.wikipedia.org/wiki/Binomial_coefficient"/> public static double BinomialCoefficient(int n, int k) { if (n < 0.0) { throw new ArgumentOutOfRangeException( nameof(n), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_NON_NEGATIVE")); } if (k < 0.0) { throw new ArgumentOutOfRangeException( nameof(k), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_NON_NEGATIVE")); } if (k > n) { throw new ArgumentOutOfRangeException( nameof(k), string.Format( CultureInfo.InvariantCulture, ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_NOT_GREATER_THAN_OTHER"), nameof(k), nameof(n))); } return(Math.Floor(0.5 + Math.Exp(LogGamma(n + 1.0) - LogGamma(k + 1.0) - LogGamma(n - k + 1.0)))); }
public void ConstructorTest() { // Valid input { var lowerBound = -1.1; var upperBound = 2.2; var distribution = new UniformDistribution( lowerBound: lowerBound, upperBound: upperBound); Assert.AreEqual( expected: lowerBound, actual: distribution.LowerBound, delta: DoubleMatrixTest.Accuracy); Assert.AreEqual( expected: upperBound, actual: distribution.UpperBound, delta: DoubleMatrixTest.Accuracy); } // upperBound == lowerBound { string STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_OTHER = string.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_OTHER"), "upperBound", "lowerBound"); ArgumentExceptionAssert.Throw( () => { new UniformDistribution(lowerBound: 1.0, upperBound: 1.0); }, expectedType: typeof(ArgumentException), expectedPartialMessage: STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_OTHER, expectedParameterName: "upperBound"); } // upperBound < lowerBound { string STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_OTHER = string.Format( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_OTHER"), "upperBound", "lowerBound"); ArgumentExceptionAssert.Throw( () => { new UniformDistribution(lowerBound: 2.0, upperBound: 1.0); }, expectedType: typeof(ArgumentException), expectedPartialMessage: STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_OTHER, expectedParameterName: "upperBound"); } }
/// <summary> /// Initializes a new instance of /// the <see cref="UnequalProbabilityRandomSampling"/> class /// by specifying the inclusion probabilities assigned to /// the population units. /// </summary> /// <param name="inclusionProbabilities"> /// The inclusion probabilities assigned to the population units.</param> /// <returns>The <see cref="UnequalProbabilityRandomSampling"/> instance /// having the specified characteristics.</returns> /// <remarks> /// <inheritdoc cref="UnequalProbabilityRandomSampling" /// path="para[@id='fromInclusion']"/> /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="inclusionProbabilities"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="inclusionProbabilities"/> has /// <see cref="DoubleMatrix.Count"/> equal to <c>1</c>.<br/> /// -or-<br/> /// <paramref name="inclusionProbabilities"/> contains entries /// whose sum differs from an integer more than .001 in /// absolute value. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="inclusionProbabilities"/> contains at /// least an entry /// not belonging to the open interval <c>]0, 1[</c>. /// </exception> public static UnequalProbabilityRandomSampling FromInclusionProbabilities( DoubleMatrix inclusionProbabilities) { #region Input validation if (inclusionProbabilities is null) { throw new ArgumentNullException(nameof(inclusionProbabilities)); } int populationSize = inclusionProbabilities.Count; if (populationSize <= 1) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_GREATER_THAN_VALUE"), "1"), nameof(inclusionProbabilities)); } var found = inclusionProbabilities.FindWhile(p => p <= 0.0 || p >= 1.0); if (null != found) { throw new ArgumentOutOfRangeException(nameof(inclusionProbabilities), string.Format( CultureInfo.InvariantCulture, ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_ENTRIES_NOT_IN_OPEN_INTERVAL"), "0", "1")); } double sum = Stat.Sum(inclusionProbabilities); double roundedSum = Math.Round(sum); if (Math.Abs(roundedSum - sum) > .001) { throw new ArgumentException( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_ENTRIES_MUST_SUM_TO_INTEGER"), nameof(inclusionProbabilities)); } int sampleSize = Convert.ToInt32(roundedSum); #endregion double delta = 1e-6; var weights = GetWeights( inclusionProbabilities, sampleSize, populationSize, delta); return(new UnequalProbabilityRandomSampling( inclusionProbabilities, weights, sampleSize)); }
/// <summary> /// Initializes a new instance of the <see cref="IndexCollection" /> class /// that contains elements from the specified array, eventually copied. /// </summary> /// <param name="indexes">The indexes to store.</param> /// <param name="copyIndexes"><c>true</c> if <paramref name="indexes"/> has to be copied; /// otherwise <c>false</c>.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="indexes" /> is <b>null</b>. /// </exception> /// <exception cref="ArgumentException"> /// The number of elements of <paramref name="indexes" /> is zero. <br/> /// -or- <br/> /// <paramref name="indexes" /> contains a negative element. /// </exception> internal IndexCollection(int[] indexes, bool copyIndexes) { if (indexes is null) { throw new ArgumentNullException(nameof(indexes)); } if (indexes.Length == 0) { throw new ArgumentException( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_NON_EMPTY"), nameof(indexes)); } this.maxIndex = -1; if (copyIndexes) { var destinationArray = new int[indexes.Length]; for (int i = 0; i < indexes.Length; i++) { int index = indexes[i]; if (index < 0) { throw new ArgumentException( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_ENTRIES_MUST_BE_NON_NEGATIVE"), nameof(indexes)); } if (index > this.maxIndex) { this.maxIndex = index; } destinationArray[i] = index; } this.indexes = destinationArray; } else { for (int i = 0; i < indexes.Length; i++) { int index = indexes[i]; if (index < 0) { throw new ArgumentException( ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_ENTRIES_MUST_BE_NON_NEGATIVE"), nameof(indexes)); } if (index > this.maxIndex) { this.maxIndex = index; } } this.indexes = indexes; } }
public void AddByCodeOnlyTest() { // code already exists { string name = "The name"; var target = new CategoricalVariable(name) { 2.0 }; ExceptionAssert.Throw( () => { target.Add(2.0); }, expectedType: typeof(InvalidOperationException), expectedMessage: ImplementationServices.GetResourceString( "STR_EXCEPT_CAT_ALREADY_EXISTS_IN_VARIABLE_LIST")); } // target is read only { string name = "The name"; var target = new CategoricalVariable(name); target.SetAsReadOnly(); ExceptionAssert.Throw( () => { target.Add(3.0); }, expectedType: typeof(InvalidOperationException), expectedMessage: ImplementationServices.GetResourceString( "STR_EXCEPT_CAT_VARIABLE_IS_READONLY")); } // Valid input { string name = "The name"; var target = new CategoricalVariable(name); double code; Category category0, category1; code = 1.0; target.Add(code); category0 = new Category(code); code = 2.0; target.Add(code); category1 = new Category(code); CategoricalVariableAssert.IsStateAsExpected( target, name, expectedCategories: new List <Category>(2) { category0, category1 }, expectedReadOnlyFlag: false); } }
internal static void ValidateSampleInput(int sampleSize) { if (sampleSize <= 0) { throw new ArgumentOutOfRangeException(nameof(sampleSize), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_POSITIVE")); } }
/// <summary> /// Initializes a new instance of the <see cref="Category"/> class. /// </summary> /// <param name="code">The category code.</param> /// <param name="label">The category label.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="label"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="label"/> is empty, or consists only of /// white-space characters. /// </exception> internal Category(double code, string label) { ImplementationServices.ThrowOnNullOrWhiteSpace( label, nameof(label)); this.Code = code; this.Label = label; }
/// <summary> /// Computes eigenvalues and eigenvectors of the /// specified symmetric real matrix. /// </summary> /// <param name="matrix"> /// The matrix containing the lower or upper triangular part of /// the matrix whose spectral decomposition must be computed. /// </param> /// <param name="lowerTriangularPart"> /// <c>true</c> if <paramref name="matrix"/> contains the lower /// triangular part of the matrix to be decomposed; /// <c>false</c> if <paramref name="matrix"/> contains /// its upper triangular part. /// </param> /// <param name="eigenvectors"> /// A matrix whose columns represent the eigenvectors /// of the decomposed matrix. /// </param> /// <returns> /// A diagonal matrix containing the eigenvalues /// of the decomposed matrix, in ascending order. /// </returns> /// <example> /// <para> /// In the following example, the spectral decomposition of a matrix is computed. /// </para> /// <para> /// <code title="Computing the Spectral decomposition of a matrix" /// source="..\Novacta.Analytics.CodeExamples\Advanced\SpectralDecompositionExample0.cs.txt" /// language="cs" /> /// </para> /// </example> /// <exception cref="ArgumentNullException"> /// <paramref name="matrix"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="matrix"/> is not square. /// </exception> public static DoubleMatrix Decompose( DoubleMatrix matrix, bool lowerTriangularPart, out DoubleMatrix eigenvectors) { #region Input validation if (matrix is null) { throw new ArgumentNullException(nameof(matrix)); } if (!matrix.IsSquare) { throw new ArgumentException( message: ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_SQUARE"), paramName: nameof(matrix)); } #endregion int m = matrix.NumberOfRows; double[] valuesArray = new double[m]; double[] vectorsArray = matrix.AsColumnMajorDenseArray(); int info = SafeNativeMethods.LAPACK.DSYEV( matrix_layout: SafeNativeMethods.LAPACK.ORDER.ColMajor, jobz: 'V', uplo: lowerTriangularPart ? 'L' : 'U', n: m, a: vectorsArray, lda: m, w: valuesArray); if (info > 0) { throw new InvalidOperationException( message: ImplementationServices.GetResourceString( "STR_EXCEPT_ALG_DOES_NOT_CONVERGE")); } DoubleMatrix eigenvalues = DoubleMatrix.Sparse(m, m, m); for (int i = 0; i < m; i++) { eigenvalues[i, i] = valuesArray[i]; } eigenvectors = DoubleMatrix.Dense(m, m, vectorsArray, copyData: false); Debug.Assert(eigenvalues != null); Debug.Assert(eigenvectors != null); return(eigenvalues); }
/// <summary> /// Gets or sets the index in the <see cref="IndexCollection" /> corresponding /// the specified position. /// </summary> /// <param name="position">The position of the index to get or set.</param> /// <value>The index at the specified position.</value> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="value"/> is negative.<br/> /// -or-<br/> /// <paramref name="position"/> is negative or greater than or equal to /// <see cref="Count"/>. /// </exception> public int this[int position] { get { if (position < 0 || position >= this.Count) { throw new ArgumentOutOfRangeException(nameof(position), ImplementationServices.GetResourceString( "STR_EXCEPT_IND_POSITION_EXCEEDS_DIMS")); } return(this.indexes[position]); } set { if (value < 0) { throw new ArgumentOutOfRangeException(nameof(value), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_NON_NEGATIVE")); } if (position < 0 || position >= this.Count) { throw new ArgumentOutOfRangeException(nameof(position), ImplementationServices.GetResourceString( "STR_EXCEPT_IND_POSITION_EXCEEDS_DIMS")); } int positionIndex = this.indexes[position]; if (positionIndex != value) { this.indexes[position] = value; if (this.maxIndex < value) { this.maxIndex = value; } else { // Here, if maxIndex == value then maxIndex is unchanged if (value < this.maxIndex) { // Here, if positionIndex != maxIndex then maxIndex is unchanged if (positionIndex == this.maxIndex) { this.UpdateCollectionMaxIndex(); } } } } } }
public void ToComplexArrayTest() { double[] doubleArray = Array.Empty <double>(); var actual = ImplementationServices.ToComplexArray(doubleArray); Complex[] expected = Array.Empty <Complex>(); ArrayAssert <Complex> .AreEqual(expected, actual); }
/// <summary> /// Computes the distance between vectors having the specified coordinates. /// </summary> /// <param name="left">The coordinates of the first vector.</param> /// <param name="right">The coordinates of the second vector.</param> /// <remarks> /// <para> /// Coordinates must be passed as row vectors. /// Let <latex>A</latex> be the /// <see cref="GetBasisMatrix">matrix representation</see> /// of this instance, and let <latex>\bc{A}{l}</latex> and /// <latex>\bc{A}{r}</latex> be /// <paramref name="left"/> and <paramref name="right"/>, /// respectively. Then /// method <see cref="Distance(DoubleMatrix, DoubleMatrix)"/> /// returns /// <latex mode="display"> /// \bdist{A}{l,r} = \bnorm{A}{l-r}, /// </latex> /// where <latex>\bnorm{A}{\cdot}</latex> is the /// <see cref="Norm(DoubleMatrix)"> /// norm</see> defined by /// basis <latex>\A</latex>. /// </para> /// </remarks> /// <returns> /// The distance between the vectors having as coordinates /// <paramref name="left"/> and <paramref name="right"/>, /// respectively.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="left"/> is <b>null</b>.<br/> /// -or-<br/> /// <paramref name="right"/> is <b>null</b>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="left"/> is not a row /// vector.<br/> /// -or-<br/> /// <paramref name="left"/> has <see cref="DoubleMatrix.Count"/> /// not equal to the <see cref="Dimension"/> of /// the <see cref="Basis"/>.<br/> /// -or-<br/> /// <paramref name="right"/> is not a row vector.<br/> /// -or-<br/> /// <paramref name="right"/> has <see cref="DoubleMatrix.Count"/> /// not equal to the <see cref="Dimension"/> of /// the <see cref="Basis"/>. /// </exception> public double Distance(DoubleMatrix left, DoubleMatrix right) { #region Input validation if (left is null) { throw new ArgumentNullException(nameof(left)); } if (!left.IsRowVector) { throw new ArgumentOutOfRangeException( nameof(left), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_ROW_VECTOR")); } int k = this.Dimension; if (left.Count != k) { throw new ArgumentOutOfRangeException( nameof(left), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_BASIS_COMPLIANT_VECTOR")); } if (right is null) { throw new ArgumentNullException(nameof(right)); } if (!right.IsRowVector) { throw new ArgumentOutOfRangeException( nameof(right), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_ROW_VECTOR")); } if (right.Count != k) { throw new ArgumentOutOfRangeException( nameof(right), ImplementationServices.GetResourceString( "STR_EXCEPT_PAR_MUST_BE_BASIS_COMPLIANT_VECTOR")); } #endregion var s = left - right; var q = this.basisScalarProducts; return(Math.Sqrt((double)(s * q * s.Transpose()))); }