internal override BaseDistribution InnerGetRatio(BaseDistribution value)
        {
            switch (value.InnerDistributionType)
            {
            case DistributionType.Number:
            {
                return(DiscreteRandomMath.Divide(this, (double)value));
            }

            case DistributionType.Discrete:
            {
                return(DiscreteRandomMath.Divide(this, (DiscreteDistribution)value));
            }

            case DistributionType.Continious:
            {
                return(DiscreteRandomMath.Divide(this, (DiscreteDistribution)(ContinuousDistribution)value));
            }

            default:
            {
                throw new DistributionsInvalidOperationException();
            }
            }
        }
        internal override BaseDistribution InnerGetSumm(BaseDistribution value)
        {
            switch (value.InnerDistributionType)
            {
            case DistributionType.Continious:
            {
                var right = (ContinuousDistribution)value;

                if (BaseDistribution is NormalDistribution && right.BaseDistribution is NormalDistribution)
                {
                    return(ContinuousRandomMath.ConvolutionOfNormalAndNormal(this, right));
                }
                else if (BaseDistribution is UniformContinuousDistribution && right.BaseDistribution is UniformContinuousDistribution)
                {
                    return(ContinuousRandomMath.ConvolutionOfUniformAndUniform(this, right));
                }
                else if (BaseDistribution is NormalDistribution && right.BaseDistribution is UniformContinuousDistribution)
                {
                    return(ContinuousRandomMath.ConvolutionOfNormalAndUniform(this, right));
                }
                else if (BaseDistribution is UniformContinuousDistribution && right.BaseDistribution is NormalDistribution)
                {
                    return(ContinuousRandomMath.ConvolutionOfNormalAndUniform(right, this));
                }
                else if (BaseDistribution is NormalDistribution && right.BaseDistribution is BhattacharjeeDistribution)
                {
                    return(ContinuousRandomMath.ConvolutionOfNormalAndBhattacharjee(this, right));
                }
                else if (BaseDistribution is BhattacharjeeDistribution && right.BaseDistribution is NormalDistribution)
                {
                    return(ContinuousRandomMath.ConvolutionOfNormalAndBhattacharjee(right, this));
                }
                else if (BaseDistribution is StudentGeneralizedDistribution && right.BaseDistribution is UniformContinuousDistribution)
                {
                    return(ContinuousRandomMath.ConvolutionOfStudentAndUniform(this, right));
                }
                else if (BaseDistribution is UniformContinuousDistribution && right.BaseDistribution is StudentGeneralizedDistribution)
                {
                    return(ContinuousRandomMath.ConvolutionOfStudentAndUniform(right, this));
                }
                else
                {
                    return(Discretize() + right.Discretize());
                }
            }

            case DistributionType.Discrete:
            {
                return(Discretize() + value);
            }

            case DistributionType.Number:
            {
                return(ContinuousRandomMath.Add(this, (double)value));
            }

            default:
                throw new DistributionsInvalidOperationException();
            }
        }
        internal override BaseDistribution InnerGetLog(BaseDistribution nBase)
        {
            switch (nBase.InnerDistributionType)
            {
            case DistributionType.Number:
            {
                return(CommonRandomMath.Log(this, (double)nBase));
            }

            case DistributionType.Continious:
            {
                return(DiscreteRandomMath.Log(Discretize(), (DiscreteDistribution)(ContinuousDistribution)nBase));
            }

            case DistributionType.Discrete:
            {
                return(DiscreteRandomMath.Log(Discretize(), (DiscreteDistribution)nBase));
            }

            default:
            {
                throw new DistributionsInvalidOperationException();
            }
            }
        }
 internal override double InnerGetPDFYbyX(double x)
 {
     try
     {
         if (x < InnerMinX || x > InnerMaxX)
         {
             return(0);
         }
         else if (Coefficient == 1 && Offset == 0)
         {
             return(BaseDistribution.ProbabilityDensityFunction(x));
         }
         else if (Coefficient == 1)
         {
             return(BaseDistribution.ProbabilityDensityFunction(x - Offset));
         }
         else
         {
             return(BaseDistribution.ProbabilityDensityFunction((x - Offset) / Coefficient) / Math.Abs(Coefficient));
         }
     }
     catch
     {
         return(0);
     }
 }
        internal override BaseDistribution InnerGetSumm(BaseDistribution value)
        {
            switch (value.InnerDistributionType)
            {
            case DistributionType.Number:
            {
                return(Mean + value.InnerMean);
            }

            case DistributionType.Continious:
            {
                return(ContinuousRandomMath.Add((ContinuousDistribution)value, Mean));
            }

            case DistributionType.Discrete:
            {
                return(DiscreteRandomMath.Add((DiscreteDistribution)value, Mean));
            }

            default:
            {
                throw new DistributionsInvalidOperationException();
            }
            }
        }
 private double GetSupport(bool min, double tolerance)
 {
     if (min)
     {
         return(BaseDistribution.InverseDistributionFunction(tolerance));
     }
     else
     {
         return(BaseDistribution.InverseDistributionFunction(1 - tolerance));
     }
 }
 internal override double InnerGetCDFYbyX(double x)
 {
     try
     {
         if (x < InnerMinX || x > InnerMaxX)
         {
             return(0);
         }
         else
         {
             return(BaseDistribution.DistributionFunction((x - Offset) / Coefficient));
         }
     }
     catch
     {
         return(0);
     }
 }
예제 #8
0
        internal bool CheckDistributions(BaseDistribution left, BaseDistribution right)
        {
            var leftCont  = left as ContinuousDistribution;
            var rightCont = right as ContinuousDistribution;

            if (BaseLeft.BaseDistribution == leftCont?.BaseDistribution && BaseRight.BaseDistribution == rightCont?.BaseDistribution)
            {
                return(true);
            }
            else if (BaseLeft.BaseDistribution == rightCont?.BaseDistribution && BaseRight.BaseDistribution == leftCont?.BaseDistribution)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        internal override BaseDistribution InnerGetRatio(BaseDistribution value)
        {
            switch (value.InnerDistributionType)
            {
            case DistributionType.Number:
            {
                return(Mean / value.InnerMean);
            }

            case DistributionType.Continious:
            case DistributionType.Discrete:
            {
                return(CommonRandomMath.Divide(Mean, value));
            }

            default:
            {
                throw new DistributionsInvalidOperationException();
            }
            }
        }
예제 #10
0
        public CorrelatedPair(BaseDistribution left, BaseDistribution right, double rho)
        {
            if (left == null)
            {
                throw new ArgumentNullException(nameof(left));
            }

            if (right == null)
            {
                throw new ArgumentNullException(nameof(right));
            }

            if (left.DistributionType != DistributionType.Continious || right.DistributionType != DistributionType.Continious)
            {
                throw new DistributionsArgumentException(DistributionsArgumentExceptionType.ForCorrelationPairBothOfDistributionsMustBeContinuous);
            }

            BaseLeft    = (ContinuousDistribution)left;
            BaseRight   = (ContinuousDistribution)right;
            Correlation = rho;
        }
        internal override BaseDistribution InnerGetPower(BaseDistribution value)
        {
            switch (value.InnerDistributionType)
            {
            case DistributionType.Number:
            {
                return(Math.Pow(Mean, (double)value));
            }

            case DistributionType.Discrete:
            case DistributionType.Continious:
            {
                return(CommonRandomMath.Power(Mean, value));
            }

            default:
            {
                throw new DistributionsInvalidOperationException();
            }
            }
        }
        internal override BaseDistribution InnerGetDifference(BaseDistribution value)
        {
            switch (value.InnerDistributionType)
            {
            case DistributionType.Continious:
            {
                return(this + (value * -1));
            }

            case DistributionType.Discrete:
            {
                return(Discretize() - value);
            }

            case DistributionType.Number:
            {
                return(ContinuousRandomMath.Sub(this, (double)value));
            }

            default:
                throw new DistributionsInvalidOperationException();
            }
        }
예제 #13
0
        private static double[] GetTrigonometricRange(double min, double max, BaseDistribution dpdf)
        {
            double[] range = new double[2];
            if (dpdf.MinX >= min && dpdf.MinX <= max)
            {
                range[0] = dpdf.MinX;
            }
            else
            {
                range[0] = min;
            }

            if (dpdf.MaxX >= min && dpdf.MaxX <= max)
            {
                range[1] = dpdf.MaxX;
            }
            else
            {
                range[1] = max;
            }

            return(range);
        }
예제 #14
0
        internal BivariateContinuousDistribution GetBivariate(BaseDistribution left, BaseDistribution right)
        {
            if (CheckDistributions(left, right))
            {
                Used = true;

                var contLeft  = (ContinuousDistribution)left;
                var contRight = (ContinuousDistribution)right;

                var samples = Math.Max(contLeft.Samples, contRight.Samples);

                if (contLeft.BaseDistribution is NormalDistribution && contRight.BaseDistribution is NormalDistribution)
                {
                    return(new BivariateNormalDistribution(left.Mean, right.Mean, left.StandardDeviation, right.StandardDeviation, Correlation * Math.Sign(contRight.Coefficient), samples));
                }
                else if (contLeft.BaseDistribution is StudentGeneralizedDistribution && contRight.BaseDistribution is StudentGeneralizedDistribution)
                {
                    var leftT  = (StudentGeneralizedDistribution)contLeft.BaseDistribution;
                    var rightT = (StudentGeneralizedDistribution)contRight.BaseDistribution;

                    if (leftT.DegreesOfFreedom != rightT.DegreesOfFreedom)
                    {
                        throw new ArgumentException();
                    }

                    return(new BivariateTDistribution(left.Mean, right.Mean, leftT.ScaleCoefficient * contLeft.Coefficient, rightT.ScaleCoefficient * contRight.Coefficient, Correlation * Math.Sign(contRight.Coefficient), leftT.DegreesOfFreedom, samples));
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            else
            {
                throw new DistributionsInvalidOperationException();
            }
        }
        internal override BaseDistribution InnerGetRatio(BaseDistribution value)
        {
            switch (value.InnerDistributionType)
            {
            case DistributionType.Continious:
            case DistributionType.Discrete:
            {
                return(Discretize() / value);
            }

            case DistributionType.Number:
            {
                if (value.InnerMean == 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.DivisionByZero);
                }

                return(ContinuousRandomMath.Divide(this, (double)value));
            }

            default:
                throw new DistributionsInvalidOperationException();
            }
        }
예제 #16
0
 public static DiscreteDistribution Power(double value, BaseDistribution dpdf)
 {
     return(Operation(dpdf, value, DistributionsOperation.PowerInv));
 }
예제 #17
0
 internal abstract BaseDistribution InnerGetRatio(BaseDistribution value);
예제 #18
0
 internal abstract BaseDistribution InnerGetPower(BaseDistribution value);
예제 #19
0
 internal abstract BaseDistribution InnerGetLog(BaseDistribution nBase);
예제 #20
0
 public static BaseDistribution Power(BaseDistribution dpdf, double value)
 {
     return(Operation(dpdf, value, DistributionsOperation.Power));
 }
예제 #21
0
 public static DiscreteDistribution Cos(BaseDistribution distribution)
 {
     return(Operation(distribution, 0, DistributionsOperation.Cos));
 }
예제 #22
0
        private static DiscreteDistribution Operation(BaseDistribution dpdf, double value, DistributionsOperation action)
        {
            int length = dpdf.InnerSamples;

            double[] yCoordinates = new double[length];
            double[] xCoordinates;

            switch (action)
            {
            case DistributionsOperation.DivideInv:
            {
                if (value == 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.DivisionOfZero);
                }

                if ((dpdf.InnerMinX < 0 && dpdf.InnerMaxX > 0) || dpdf.InnerMinX == 0 || dpdf.InnerMaxX == 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.DivisionByZeroCrossingRandom);
                }

                double r1 = value / dpdf.InnerMinX;
                double r2 = value / dpdf.InnerMaxX;
                xCoordinates = GenerateXAxis(r1, r2, length, out _);

                for (int i = 0; i < length; i++)
                {
                    double z = xCoordinates[i];
                    double d = value / z;
                    double k = Math.Abs(value) / Math.Pow(z, 2);

                    yCoordinates[i] = dpdf.InnerGetPDFYbyX(d) * k;
                }

                break;
            }

            case DistributionsOperation.Power:
            {
                if (value == 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.ExponentialOfRandomInZeroPower);
                }

                if (value < 0 && ((dpdf.InnerMinX < 0 && dpdf.InnerMaxX > 0) || dpdf.InnerMinX == 0 || dpdf.InnerMaxX == 0))
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.ExponentialOfZeroCrossingRandomInNegativePower);
                }

                bool evenPower    = Math.Abs(value % 2) == 0;
                bool naturalPower = value - (int)value == 0;

                if (dpdf.InnerMinX < 0 && !naturalPower)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.ExponentialOfNotPositiveRandomInIrrationalPower);
                }

                double r1 = Math.Pow(dpdf.InnerMinX, value);
                double r2 = Math.Pow(dpdf.InnerMaxX, value);

                if (dpdf.InnerMinX < 0 && dpdf.InnerMaxX > 0 && evenPower)
                {
                    r2 = Math.Max(r1, r2);
                    r1 = 0;
                }

                xCoordinates = GenerateXAxis(r1, r2, length, out _);

                for (int i = 0; i < length; i++)
                {
                    double d = Math.Sign(xCoordinates[i]) * Math.Pow(Math.Abs(xCoordinates[i]), 1d / value);
                    double k = Math.Abs(Math.Pow(Math.Abs(xCoordinates[i]), (1d - value) / value) / value);

                    yCoordinates[i] = dpdf.InnerGetPDFYbyX(d) * k;

                    if (evenPower)
                    {
                        yCoordinates[i] += dpdf.InnerGetPDFYbyX(-d) * k;
                    }
                }

                break;
            }

            case DistributionsOperation.PowerInv:
            {
                if (value == 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.ExponentialOfZeroInRandomPower);
                }
                else if (value < 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.ExponentialOfNegativeInRandomPower);
                }
                else if (value == 1)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.ExponentialOfOneInRandomPower);
                }

                double r1 = Math.Pow(value, dpdf.InnerMinX);
                double r2 = Math.Pow(value, dpdf.InnerMaxX);

                xCoordinates = GenerateXAxis(r1, r2, length, out _);

                for (int i = 0; i < length; i++)
                {
                    double d = Math.Log(xCoordinates[i], value);
                    double k = Math.Abs(Math.Log(value) * xCoordinates[i]);

                    yCoordinates[i] = dpdf.InnerGetPDFYbyX(d) / k;
                }

                break;
            }

            case DistributionsOperation.Log:
            {
                if (value == 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.LogarithmWithZeroBase);
                }
                else if (value < 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.LogarithmWithNegativeBase);
                }
                else if (value == 1)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.LogarithmWithOneBase);
                }

                if (dpdf.InnerMinX <= 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.LogarithmOfNotPositiveRandom);
                }

                double r1 = Math.Log(dpdf.InnerMinX, value);
                double r2 = Math.Log(dpdf.InnerMaxX, value);

                xCoordinates = GenerateXAxis(r1, r2, length, out _);

                for (int i = 0; i < length; i++)
                {
                    double d = Math.Pow(value, xCoordinates[i]);
                    double k = Math.Abs(Math.Log(value) * d);

                    yCoordinates[i] = dpdf.InnerGetPDFYbyX(d) * k;
                }
                break;
            }

            case DistributionsOperation.LogInv:
            {
                if (dpdf.InnerMinX <= 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.LogarithmWithNotPositiveRandomBase);
                }

                if ((dpdf.InnerMinX < 1 && dpdf.InnerMaxX > 1) || dpdf.InnerMinX == 1 || dpdf.InnerMaxX == 1)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.LogarithmWithOneCrossingRandomBase);
                }

                if (value == 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.LogarithmOfZeroValue);
                }

                if (value < 0)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.LogarithmOfNegativeValue);
                }

                double r1 = Math.Log(value, dpdf.InnerMaxX);
                double r2 = Math.Log(value, dpdf.InnerMinX);

                xCoordinates = GenerateXAxis(r1, r2, length, out _);

                for (int i = 0; i < length; i++)
                {
                    double d = Math.Pow(value, 1d / xCoordinates[i]);

                    double k = Math.Abs((d * Math.Log(value)) / Math.Pow(xCoordinates[i], 2));
                    yCoordinates[i] = dpdf.InnerGetPDFYbyX(d) * k;
                }

                break;
            }

            case DistributionsOperation.Abs:
            {
                double r1 = Math.Abs(dpdf.InnerMinX);
                double r2 = Math.Abs(dpdf.InnerMaxX);

                if (dpdf.InnerMinX <= 0 && dpdf.InnerMaxX >= 0)
                {
                    r2 = Math.Max(r1, r2);
                    r1 = 0;
                }

                xCoordinates = GenerateXAxis(r1, r2, length, out _);

                for (int i = 0; i < length; i++)
                {
                    double zPow = xCoordinates[i];

                    yCoordinates[i] = dpdf.InnerGetPDFYbyX(zPow) + dpdf.InnerGetPDFYbyX(-zPow);
                }

                break;
            }

            case DistributionsOperation.Sin:
            {
                double r1 = -1;
                double r2 = 1;

                xCoordinates = GenerateXAxis(r1, r2, length, out _);

                // Max asin [-PI/2, PI/2]
                int minJ = (int)(dpdf.MinX / (2 * Math.PI)) - 1;
                int maxJ = (int)(dpdf.MaxX / (2 * Math.PI)) + 1;

                for (int i = 0; i < length; i++)
                {
                    double z = xCoordinates[i];

                    double arcsin = Math.Asin(z);
                    double k      = 1d / Math.Sqrt(1 - Math.Pow(z, 2));

                    for (double j = minJ; j <= maxJ; j++)
                    {
                        double v = dpdf.InnerGetPDFYbyX((Math.PI * 2 * j) - (Math.PI + arcsin)) +
                                   dpdf.InnerGetPDFYbyX((Math.PI * 2 * j) + arcsin);

                        if (v != 0)
                        {
                            yCoordinates[i] += k * v;
                        }
                    }
                }

                break;
            }

            case DistributionsOperation.Cos:
            {
                // https://mathoverflow.net/questions/35260/resultant-probability-distribution-when-taking-the-cosine-of-gaussian-distribute
                // TODO: Verify for trigonometric functions work properly. And remove range?
                _ = GetTrigonometricRange(-1, 1, dpdf);

                double r1 = -1;
                double r2 = 1;

                xCoordinates = GenerateXAxis(r1, r2, length, out _);

                // Max acos [0, PI]
                int minJ = (int)(dpdf.MinX / (2 * Math.PI)) - 1;
                int maxJ = (int)(dpdf.MaxX / (2 * Math.PI)) + 1;

                for (int i = 0; i < length; i++)
                {
                    double z = xCoordinates[i];

                    double acos = Math.Acos(z);
                    double k    = 1d / Math.Sqrt(1 - Math.Pow(z, 2));

                    for (double j = minJ; j <= maxJ; j++)
                    {
                        double v = dpdf.InnerGetPDFYbyX((2 * (j + 1) * Math.PI) - acos) +
                                   dpdf.InnerGetPDFYbyX((2 * j * Math.PI) + acos);

                        if (v != 0)
                        {
                            yCoordinates[i] += k * v;
                        }
                    }
                }

                break;
            }

            case DistributionsOperation.Tan:
            {
                if (dpdf.MaxX - dpdf.MinX >= Math.PI ||
                    dpdf.MinX % Math.PI <= -Math.PI / 2 ||
                    dpdf.MaxX % Math.PI >= Math.PI / 2)
                {
                    throw new DistributionsInvalidOperationException(DistributionsInvalidOperationExceptionType.TangentOfValueCrossingAsymptote);
                }

                double r1 = Math.Tan(dpdf.MinX);
                double r2 = Math.Tan(dpdf.MaxX);

                xCoordinates = GenerateXAxis(r1, r2, length, out _);

                int j = dpdf.Mean < 0 ? (int)(dpdf.MinX / Math.PI) : (int)(dpdf.MaxX / Math.PI);

                for (int i = 0; i < length; i++)
                {
                    double z = xCoordinates[i];

                    double atan = Math.Atan(z);
                    double k    = 1d / (Math.Pow(z, 2) + 1);

                    double v = dpdf.InnerGetPDFYbyX((-Math.PI / 2d) + (Math.PI * j)) +
                               dpdf.InnerGetPDFYbyX(atan + (j * Math.PI));

                    if (v != 0)
                    {
                        yCoordinates[i] = k * v;
                    }
                }

                break;
            }

            default:
            {
                throw new NotImplementedException();
            }
            }

            return(new DiscreteDistribution(xCoordinates, yCoordinates));
        }
예제 #23
0
 public static DiscreteDistribution Tan(BaseDistribution distribution)
 {
     return(Operation(distribution, 0, DistributionsOperation.Tan));
 }
예제 #24
0
 public static DiscreteDistribution Log(BaseDistribution dpdf, double nBase)
 {
     return(Operation(dpdf, nBase, DistributionsOperation.Log));
 }
예제 #25
0
 internal abstract BaseDistribution InnerGetProduct(BaseDistribution value);
예제 #26
0
 public static DiscreteDistribution Abs(BaseDistribution dpdf)
 {
     return(Operation(dpdf, 0, DistributionsOperation.Abs));
 }
 internal override double InnerQuantile(double p)
 {
     return((BaseDistribution.InverseDistributionFunction(p) * Coefficient) + Offset);
 }
예제 #28
0
 public static DiscreteDistribution Log(double value, BaseDistribution nBase)
 {
     return(Operation(nBase, value, DistributionsOperation.LogInv));
 }
예제 #29
0
 public static DiscreteDistribution Divide(double value, BaseDistribution dpdf)
 {
     return(Operation(dpdf, value, DistributionsOperation.DivideInv));
 }
예제 #30
0
 internal abstract BaseDistribution InnerGetDifference(BaseDistribution value);