public static double PDFIntegration(double x, double alpha, double precision, ref object tempStorage)
 {
     if (alpha < 1)
     {
         GetAlt1GnParameter(x, alpha, out var factorp, out var facdiv, out var dev, out var logPdfPrefactor);
         var intg = new Alt1GnI(factorp, facdiv, logPdfPrefactor, alpha, dev);
         if (intg.IsMaximumLeftHandSide())
         {
             return(intg.PDFIntegrate(ref tempStorage, precision));
         }
         else
         {
             return(new Alt1GnD(factorp, facdiv, logPdfPrefactor, alpha, dev).Integrate(ref tempStorage, precision));
         }
     }
     else
     {
         GetAgt1GnParameter(x, alpha, out var factorp, out var factorw, out var dev, out var logPdfPrefactor);
         var intg = new Agt1GnI(factorp, factorw, logPdfPrefactor, alpha, dev);
         if (intg.IsMaximumLeftHandSide())
         {
             return(intg.Integrate(ref tempStorage, precision));
         }
         else
         {
             return(new Agt1GnD(factorp, factorw, logPdfPrefactor, alpha, dev).Integrate(ref tempStorage, precision));
         }
     }
 }
        private static void CDFMethodForPositiveX(double x, double alpha, ref object tempStorage, double precision, out double integFromXZero, out double integFromXInfinity)
        {
            const double offs = 0.5;

            if (alpha < 1)
            {
                GetAlt1GnParameter(x, alpha, out var factorp, out var facdiv, out var dev, out var logPdfPrefactor);
                var inc = new Alt1GnI(factorp, facdiv, logPdfPrefactor, alpha, dev);
                if (inc.IsMaximumLeftHandSide())
                {
                    integFromXZero     = inc.CDFIntegrate(ref tempStorage, precision) / Math.PI;
                    integFromXInfinity = offs - integFromXZero;
                }
                else
                {
                    integFromXInfinity = new Alt1GnD(factorp, facdiv, logPdfPrefactor, alpha, dev).CDFIntegrate(ref tempStorage, precision) / Math.PI;
                    integFromXZero     = offs - integFromXInfinity;
                }
            }
            else if (alpha == 1)
            {
                if (x <= 1)
                {
                    integFromXZero     = Math.Atan(x) / Math.PI;
                    integFromXInfinity = offs - integFromXZero;
                }
                else
                {
                    integFromXInfinity = Math.Atan(1 / x) / Math.PI;
                    integFromXZero     = offs - integFromXInfinity;
                }
            }
            else // if(alpha>1)
            {
                GetAgt1GnParameter(x, alpha, out var factorp, out var factorw, out var dev, out var logPdfPrefactor);
                var inc = new Agt1GnI(factorp, factorw, logPdfPrefactor, alpha, dev);
                if (inc.IsMaximumLeftHandSide())
                {
                    integFromXInfinity = inc.CDFIntegrate(ref tempStorage, precision) / Math.PI;
                    integFromXZero     = offs - integFromXInfinity;
                }
                else
                {
                    integFromXZero     = new Agt1GnD(factorp, factorw, logPdfPrefactor, alpha, dev).CDFIntegrate(ref tempStorage, precision) / Math.PI;
                    integFromXInfinity = offs - integFromXZero;
                }
            }
        }
		public static void CDFMethodForPositiveX(double x, double alpha, double gamma, double aga, ref object tempStorage, double precision, out double integFromXZero, out double integFromXInfinity, out double offs)
		{
			if (alpha <= 0)
				throw new ArgumentException("Alpha must be in the range alpha>0");

			if (alpha < 1)
			{
				if (gamma <= 0)
				{
					offs = 1 - 0.5 * aga;
					if (x == 0)
					{
						integFromXZero = 0;
						integFromXInfinity = offs;
					}
					else // x != 0
					{
						double factorp, facdiv, dev, logPdfPrefactor;
						GetAlt1GnParameterByGamma(x, alpha, gamma, aga, out factorp, out facdiv, out dev, out logPdfPrefactor);
						Alt1GnI inc = new Alt1GnI(factorp, facdiv, logPdfPrefactor, alpha, dev);
						if (inc.IsMaximumLeftHandSide())
						{
							integFromXZero = inc.CDFIntegrate(ref tempStorage, precision) / Math.PI;
							integFromXInfinity = offs - integFromXZero;
						}
						else
						{
							integFromXInfinity = new Alt1GnD(factorp, facdiv, logPdfPrefactor, alpha, dev).CDFIntegrate(ref tempStorage, precision) / Math.PI;
							integFromXZero = offs - integFromXInfinity;
						}
					}
				}
				else // gamma>0
				{
					offs = 0.5 * aga;
					if (x == 0)
					{
						integFromXZero = 0;
						integFromXInfinity = offs;
					}
					else // x!=0
					{
						double factorp, facdiv, dev, logPdfPrefactor;
						GetAlt1GpParameterByGamma(x, alpha, gamma, aga, out factorp, out facdiv, out dev, out logPdfPrefactor);
						Alt1GpI inc = new Alt1GpI(factorp, facdiv, logPdfPrefactor, alpha, dev);
						if (inc.IsMaximumLeftHandSide())
						{
							integFromXZero = inc.CDFIntegrate(ref tempStorage, precision) / Math.PI;
							integFromXInfinity = offs - integFromXZero;
						}
						else
						{
							integFromXInfinity = new Alt1GpD(factorp, facdiv, logPdfPrefactor, alpha, dev).CDFIntegrate(ref tempStorage, precision) / Math.PI;
							integFromXZero = offs - integFromXInfinity;
						}
					}
				}
			}
			else if (alpha == 1)
			{
				double a; // = Math.Cos(gamma*Math.PI/2);
				double b; // = Math.Sin(gamma*Math.PI/2);
				offs = 0.5;
				a = SinXPiBy2(aga); // for alpha=1 aga is 1-gamma or -1+gamma, thus we can turn cosine into sine
				b = SinXPiBy2(gamma); // for b it is not important to have high accuracy with gamma=1 or -1
				double arg = (b + x) / a;
				if (arg <= 1)
				{
					integFromXZero = Math.Atan(arg) / Math.PI;
					integFromXInfinity = offs - integFromXZero;
				}
				else
				{
					integFromXInfinity = Math.Atan(1 / arg) / Math.PI;
					integFromXZero = offs - integFromXInfinity;
				}
			}
			else if (alpha <= 2)
			{
				double xinv = Math.Pow(x, -alpha);
				double alphainv = 1 / alpha;
				double gammainv = (gamma - alpha + 1) / alpha;
				double againv = aga;
				if (gamma > 0)
					againv = gammainv > 0 ? 2 * (alpha - 1) + aga : 2 * (2 - alpha) - aga;
				else
					againv = aga;

				CDFMethodForPositiveX(xinv, alphainv, gammainv, againv, ref tempStorage, precision, out integFromXZero, out integFromXInfinity, out offs);
				double h = integFromXZero;
				integFromXZero = integFromXInfinity / alpha;
				integFromXInfinity = h / alpha;
				offs /= alpha;
			}
			else
			{
				throw new ArgumentException("Alpha not in the range 0<alpha<=2");
			}
		}
		/// <summary>
		/// Special case for alpha &lt; 1 and gamma near to -alpha (i.e. gamma at the negative border).
		/// Here gamma was set to -alpha*(1-dev*2/Pi).
		/// </summary>
		/// <param name="x"></param>
		/// <param name="alpha"></param>
		/// <param name="gamma"></param>
		/// <param name="aga"></param>
		/// <param name="temp"></param>
		/// <param name="precision"></param>
		/// <returns></returns>
		public static double PDFIntegralAlt1Gn(double x, double alpha, double gamma, double aga, ref object temp, double precision)
		{
			double factorp, facdiv, dev, prefactor;
			GetAlt1GnParameterByGamma(x, alpha, gamma, aga, out factorp, out facdiv, out dev, out prefactor);

			double integrand;
			Alt1GnI ingI = new Alt1GnI(factorp, facdiv, prefactor, alpha, dev);
			if (ingI.IsMaximumLeftHandSide())
			{
				integrand = ingI.PDFIntegrate(ref temp, precision);
				if (double.IsNaN(integrand))
					integrand = new Alt1GnD(factorp, facdiv, prefactor, alpha, dev).Integrate(ref temp, precision);
			}
			else
			{
				integrand = new Alt1GnD(factorp, facdiv, prefactor, alpha, dev).Integrate(ref temp, precision);
				if (double.IsNaN(integrand))
					integrand = ingI.PDFIntegrate(ref temp, precision);
			}

			return integrand;
		}
		private static void CDFMethodForPositiveX(double x, double alpha, ref object tempStorage, double precision, out double integFromXZero, out double integFromXInfinity)
		{
			const double offs = 0.5;

			if (alpha < 1)
			{
				double factorp, facdiv, dev, logPdfPrefactor;
				GetAlt1GnParameter(x, alpha, out factorp, out facdiv, out dev, out logPdfPrefactor);
				Alt1GnI inc = new Alt1GnI(factorp, facdiv, logPdfPrefactor, alpha, dev);
				if (inc.IsMaximumLeftHandSide())
				{
					integFromXZero = inc.CDFIntegrate(ref tempStorage, precision) / Math.PI;
					integFromXInfinity = offs - integFromXZero;
				}
				else
				{
					integFromXInfinity = new Alt1GnD(factorp, facdiv, logPdfPrefactor, alpha, dev).CDFIntegrate(ref tempStorage, precision) / Math.PI;
					integFromXZero = offs - integFromXInfinity;
				}
			}
			else if (alpha == 1)
			{
				if (x <= 1)
				{
					integFromXZero = Math.Atan(x) / Math.PI;
					integFromXInfinity = offs - integFromXZero;
				}
				else
				{
					integFromXInfinity = Math.Atan(1 / x) / Math.PI;
					integFromXZero = offs - integFromXInfinity;
				}
			}
			else // if(alpha>1)
			{
				double factorp, factorw, dev, logPdfPrefactor;
				GetAgt1GnParameter(x, alpha, out factorp, out factorw, out dev, out logPdfPrefactor);
				Agt1GnI inc = new Agt1GnI(factorp, factorw, logPdfPrefactor, alpha, dev);
				if (inc.IsMaximumLeftHandSide())
				{
					integFromXInfinity = inc.CDFIntegrate(ref tempStorage, precision) / Math.PI;
					integFromXZero = offs - integFromXInfinity;
				}
				else
				{
					integFromXZero = new Agt1GnD(factorp, factorw, logPdfPrefactor, alpha, dev).CDFIntegrate(ref tempStorage, precision) / Math.PI;
					integFromXInfinity = offs - integFromXZero;
				}
			}
		}
		public static double PDFIntegration(double x, double alpha, double precision, ref object tempStorage)
		{
			if (alpha < 1)
			{
				double factorp, facdiv, dev, logPdfPrefactor;
				GetAlt1GnParameter(x, alpha, out factorp, out facdiv, out dev, out logPdfPrefactor);
				Alt1GnI intg = new Alt1GnI(factorp, facdiv, logPdfPrefactor, alpha, dev);
				if (intg.IsMaximumLeftHandSide())
					return intg.PDFIntegrate(ref tempStorage, precision);
				else
					return new Alt1GnD(factorp, facdiv, logPdfPrefactor, alpha, dev).Integrate(ref tempStorage, precision);
			}
			else
			{
				double factorp, factorw, dev, logPdfPrefactor;
				GetAgt1GnParameter(x, alpha, out factorp, out factorw, out dev, out logPdfPrefactor);
				Agt1GnI intg = new Agt1GnI(factorp, factorw, logPdfPrefactor, alpha, dev);
				if (intg.IsMaximumLeftHandSide())
					return intg.Integrate(ref tempStorage, precision);
				else
					return new Agt1GnD(factorp, factorw, logPdfPrefactor, alpha, dev).Integrate(ref tempStorage, precision);
			}
		}