예제 #1
0
        /// <summary>
        ///     Checks whether the given <see cref="MathProgram" /> computes a value that is consistently equivalent to that
        ///     computed
        ///     by another program according to some margin. The method works by substituting the variables in both programs'
        ///     expressions by random values for a certain number of trials. In each trial, the difference between the values
        ///     computed by both programs is calculated. If the difference is less than a given margin for all the trials, then the
        ///     programs are considered to be value-equivalent.
        /// </summary>
        /// <param name="program">The first program that we want to test.</param>
        /// <param name="other">The second program that we want to test.</param>
        /// <param name="margin">
        ///     The margin used to compare against the difference of values computed by both expressions in each
        ///     trial.
        /// </param>
        /// <param name="numTrials">The number of trials used to discern whether the given programs are equivalent.</param>
        /// <returns><c>True</c> if the given programs are considered to be value-equivalent, <c>False</c> otherwise.</returns>
        public static bool IsValueEquivalent(
            this ITreeProgram <double> program, ITreeProgram <double> other, double margin = DEFAULT_MARGIN,
            uint numTrials = DEFAULT_NUM_TRIALS)
        {
            // checks null
            if (program == null || other == null)
            {
                return(false);
            }

            // checks equivalence
            if (program.Equals(other))
            {
                return(true);
            }

            // checks expression or constant equivalence after simplification
            program = program.Simplify();
            other   = other.Simplify();
            if (program.Equals(other) ||
                program.IsConstant() && other.IsConstant() && Math.Abs(program.Compute() - other.Compute()) < margin)
            {
                return(true);
            }

            // gets RMSE by replacing the values of the variables in some number of trials
            return(program.GetValueRmsd(other, numTrials) <= margin);
        }