// Calculate the Gauthier coefficients
        public double[] GauthierCoefficients(double kappa, double theta, double v0, double S, double K, double T, double rf, double q)
        {
            BlackScholesPrice BS = new BlackScholesPrice();
            double            x  = Math.Log(S);
            double            kT = kappa * T;

            double m0   = Math.Exp(-kT) * (Math.Exp(kT) - 1) / kappa;
            double m1   = T - m0;
            double varT = m0 * v0 + m1 * theta;

            double p0 = Math.Exp(-kT) * (Math.Exp(kT) - kT - 1) / kappa / kappa;
            double p1 = Math.Exp(-kT) * (Math.Exp(kT) * (kT - 2) + kT + 2) / kappa / kappa;

            double q0 = Math.Exp(-kT) * (2 * Math.Exp(kT) - kT * (kT + 2) - 2) / 2 / kappa / kappa / kappa;
            double q1 = Math.Exp(-kT) * (2 * Math.Exp(kT) * (kT - 3) + kT * (kT + 4) + 6) / 2 / kappa / kappa / kappa;

            double r0 = Math.Exp(-2 * kT) * (2 * Math.Exp(2 * kT) - 4 * Math.Exp(kT) * kT - 2) / 4 / kappa / kappa / kappa;
            double r1 = Math.Exp(-2 * kT) * (Math.Exp(2 * kT) * (2 * kT - 5) + 4 * Math.Exp(kT) * (kT + 1) + 1) / 4 / kappa / kappa / kappa;

            double[] BSderiv = BS.BlackScholesDerivatives(kappa, theta, v0, S, K, T, rf, q);
            double   P11     = BSderiv[0];
            double   P21     = BSderiv[1];
            double   P02     = BSderiv[2];
            double   P22     = BSderiv[3];
            double   y       = varT;

            // Black Scholes Put Price
            double g     = Math.Pow(y, -0.5) * (-x + Math.Log(K) - (rf - q) * T) - 0.5 * Math.Sqrt(y);
            double f     = Math.Pow(y, -0.5) * (-x + Math.Log(K) - (rf - q) * T) + 0.5 * Math.Sqrt(y);
            double BSPut = K * Math.Exp(-rf * T) * BS.NormCDF(f) - S * Math.Exp(-q * T) * BS.NormCDF(g);

            double A = BSPut;
            double B = (v0 * r0 + theta * r1) * P02;
            double C = (v0 * p0 + theta * p1) * P11;
            double D = (v0 * q0 + theta * q1) * P21 + 0.5 * Math.Pow(v0 * p0 + theta * p1, 2) * P22;

            double[] output = new double[4];
            output[0] = A;
            output[1] = B;
            output[2] = C;
            output[3] = D;

            return(output);
        }
        // public double Algorithm for Black Scholes Implied Volatility =================================================================================
        public double BisecBSIV(string PutCall, double S, double K, double rf, double q, double T, double a, double b, double MktPrice, double Tol, int MaxIter)
        {
            BlackScholesPrice BS       = new BlackScholesPrice();
            double            lowCdif  = MktPrice - BS.BlackScholes(S, K, T, rf, q, a, PutCall);
            double            highCdif = MktPrice - BS.BlackScholes(S, K, T, rf, q, b, PutCall);
            double            BSIV     = 0.0;
            double            midP;

            if (lowCdif * highCdif > 0.0)
            {
                BSIV = -1.0;
            }
            else
            {
                for (int x = 0; x <= MaxIter; x++)
                {
                    midP = (a + b) / 2.0;
                    double midCdif = MktPrice - BS.BlackScholes(S, K, T, rf, q, midP, PutCall);
                    if (Math.Abs(midCdif) < Tol)
                    {
                        break;
                    }
                    else
                    {
                        if (midCdif > 0.0)
                        {
                            a = midP;
                        }
                        else
                        {
                            b = midP;
                        }
                    }
                    BSIV = midP;
                }
            }
            return(BSIV);
        }