示例#1
0
        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);
            }
        }
示例#2
0
                /// <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);
                }
示例#3
0
                /// <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));
            }
        }
示例#5
0
        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);
        }
示例#7
0
        /// <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));
            }
        }
示例#8
0
        /// <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()));
        }
示例#9
0
 /// <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;
     }
 }
示例#10
0
        /// <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"));
            }
        }
示例#11
0
        /// <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));
        }
示例#12
0
        /// <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);
        }
示例#13
0
        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);
        }
示例#14
0
        /// <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);
        }
示例#15
0
        /// <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);
        }
示例#16
0
                /// <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);
                }
示例#17
0
        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);
                }
            }
        }
示例#18
0
        /// <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));
        }
示例#19
0
        /// <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 &amp; \cdots &amp;\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;
        }
示例#20
0
        /// <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))));
        }
示例#21
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");
            }
        }
示例#22
0
        /// <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));
        }
示例#23
0
        /// <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"));
     }
 }
示例#26
0
        /// <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;
        }
示例#27
0
        /// <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);
        }
示例#28
0
        /// <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);
        }
示例#30
0
        /// <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())));
        }