⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pfqfn.cpp

📁 Quantitative Finance C++ source code, asian option pricer
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*     *                                                              * */
/*     *  Description : Accepts two arrays and returns the product.   * */
/*     *    L and RMAX are the size of the arrays and the number of   * */
/*     *    digits needed to represent the numbers with the required  * */
/*     *    accuracy.                                                 * */
/*     *                                                              * */
/*     *  Subprograms called: none                                    * */
/*     *                                                              * */
/*     **************************************************************** */
/* Subroutine */ int armult_(doublereal *a, doublereal *b, doublereal *c__, 
	doublereal *z__, integer *l, doublereal *rmax)
{
    /* System generated locals */
    integer i__1;
    doublereal d__1;

    /* Builtin functions */
    double d_sign(doublereal *, doublereal *), d_int(doublereal *);

    /* Local variables */
    static integer i__;
    static doublereal b2, carry;

    /* Parameter adjustments */
    ++z__;
    ++c__;
    ++a;

    /* Function Body */
    z__[-1] = d_sign(&consts_1.one, b) * a[-1];
    b2 = abs(*b);
    z__[*l + 1] = a[*l + 1];
    i__1 = *l;
    for (i__ = 0; i__ <= i__1; ++i__) {
	z__[i__] = consts_1.zero;
/* L10: */
    }
    if (b2 <= consts_1.eps || a[1] <= consts_1.eps) {
	z__[-1] = consts_1.one;
	z__[*l + 1] = consts_1.zero;
	goto L60;
    }
    for (i__ = *l; i__ >= 1; --i__) {
	z__[i__] = a[i__] * b2 + z__[i__];
	if (z__[i__] >= *rmax) {
	    d__1 = z__[i__] / *rmax;
	    carry = d_int(&d__1);
	    z__[i__] -= carry * *rmax;
	    z__[i__ - 1] = carry;
	}
/* L20: */
    }
    if (z__[0] < consts_1.half) {
	goto L50;
    }
    for (i__ = *l; i__ >= 1; --i__) {
	z__[i__] = z__[i__ - 1];
/* L30: */
    }
    z__[*l + 1] += consts_1.one;
    if (z__[1] >= *rmax) {
	for (i__ = *l; i__ >= 1; --i__) {
	    z__[i__] = z__[i__ - 1];
/* L40: */
	}
	d__1 = z__[1] / *rmax;
	carry = d_int(&d__1);
	z__[2] -= carry * *rmax;
	z__[1] = carry;
	z__[*l + 1] += consts_1.one;
    }
    z__[0] = consts_1.zero;
L50:
L60:
    i__1 = *l + 1;
    for (i__ = -1; i__ <= i__1; ++i__) {
	c__[i__] = z__[i__];
/* L70: */
    }
    if (c__[1] < consts_1.half) {
	c__[-1] = consts_1.one;
	c__[*l + 1] = consts_1.zero;
    }
    return 0;
} /* armult_ */

/*     **************************************************************** */
/*     *                                                              * */
/*     *                 SUBROUTINE CMPADD                            * */
/*     *                                                              * */
/*     *                                                              * */
/*     *  Description : Takes two arrays representing one real and    * */
/*     *    one imaginary part, and adds two arrays representing      * */
/*     *    another complex number and returns two array holding the  * */
/*     *    complex sum.                                              * */
/*     *              (CR,CI) = (AR+BR, AI+BI)                        * */
/*     *                                                              * */
/*     *  Subprograms called: ARADD                                   * */
/*     *                                                              * */
/*     **************************************************************** */
/* Subroutine */ int cmpadd_(doublereal *ar, doublereal *ai, doublereal *br, 
	doublereal *bi, doublereal *cr, doublereal *ci, doublereal *wk1, 
	integer *l, doublereal *rmax)
{
    extern /* Subroutine */ int aradd_(doublereal *, doublereal *, doublereal 
	    *, doublereal *, integer *, doublereal *);

    /* Parameter adjustments */
    ++wk1;
    ++ci;
    ++cr;
    ++bi;
    ++br;
    ++ai;
    ++ar;

    /* Function Body */
    aradd_(&ar[-1], &br[-1], &cr[-1], &wk1[-1], l, rmax);
    aradd_(&ai[-1], &bi[-1], &ci[-1], &wk1[-1], l, rmax);
    return 0;
} /* cmpadd_ */

/*     **************************************************************** */
/*     *                                                              * */
/*     *                 SUBROUTINE CMPSUB                            * */
/*     *                                                              * */
/*     *                                                              * */
/*     *  Description : Takes two arrays representing one real and    * */
/*     *    one imaginary part, and subtracts two arrays representing * */
/*     *    another complex number and returns two array holding the  * */
/*     *    complex sum.                                              * */
/*     *              (CR,CI) = (AR+BR, AI+BI)                        * */
/*     *                                                              * */
/*     *  Subprograms called: ARADD                                   * */
/*     *                                                              * */
/*     **************************************************************** */
/* Subroutine */ int cmpsub_(doublereal *ar, doublereal *ai, doublereal *br, 
	doublereal *bi, doublereal *cr, doublereal *ci, doublereal *wk1, 
	doublereal *wk2, integer *l, doublereal *rmax)
{
    extern /* Subroutine */ int arsub_(doublereal *, doublereal *, doublereal 
	    *, doublereal *, doublereal *, integer *, doublereal *);

    /* Parameter adjustments */
    ++wk2;
    ++wk1;
    ++ci;
    ++cr;
    ++bi;
    ++br;
    ++ai;
    ++ar;

    /* Function Body */
    arsub_(&ar[-1], &br[-1], &cr[-1], &wk1[-1], &wk2[-1], l, rmax);
    arsub_(&ai[-1], &bi[-1], &ci[-1], &wk1[-1], &wk2[-1], l, rmax);
    return 0;
} /* cmpsub_ */

/*     **************************************************************** */
/*     *                                                              * */
/*     *                 SUBROUTINE CMPMUL                            * */
/*     *                                                              * */
/*     *                                                              * */
/*     *  Description : Takes two arrays representing one real and    * */
/*     *    one imaginary part, and multiplies it with two arrays     * */
/*     *    representing another complex number and returns the       * */
/*     *    complex product.                                          * */
/*     *                                                              * */
/*     *  Subprograms called: ARMULT, ARSUB, ARADD                    * */
/*     *                                                              * */
/*     **************************************************************** */
/* Subroutine */ int cmpmul_(doublereal *ar, doublereal *ai, doublereal *br, 
	doublereal *bi, doublereal *cr, doublereal *ci, doublereal *wk1, 
	doublereal *wk2, doublereal *cr2, doublereal *d1, doublereal *d2, 
	doublereal *wk6, integer *l, doublereal *rmax)
{
    /* System generated locals */
    integer i__1;

    /* Local variables */
    static integer i__;
    extern /* Subroutine */ int aradd_(doublereal *, doublereal *, doublereal 
	    *, doublereal *, integer *, doublereal *), arsub_(doublereal *, 
	    doublereal *, doublereal *, doublereal *, doublereal *, integer *,
	     doublereal *), armult_(doublereal *, doublereal *, doublereal *, 
	    doublereal *, integer *, doublereal *);

    /* Parameter adjustments */
    ++d2;
    ++d1;
    ++cr2;
    ++wk2;
    ++wk1;
    ++ci;
    ++cr;
    ++ai;
    ++ar;

    /* Function Body */
    armult_(&ar[-1], br, &d1[-1], wk6, l, rmax);
    armult_(&ai[-1], bi, &d2[-1], wk6, l, rmax);
    arsub_(&d1[-1], &d2[-1], &cr2[-1], &wk1[-1], &wk2[-1], l, rmax);
    armult_(&ar[-1], bi, &d1[-1], wk6, l, rmax);
    armult_(&ai[-1], br, &d2[-1], wk6, l, rmax);
    aradd_(&d1[-1], &d2[-1], &ci[-1], &wk1[-1], l, rmax);
    i__1 = *l + 1;
    for (i__ = -1; i__ <= i__1; ++i__) {
	cr[i__] = cr2[i__];
/* L10: */
    }
    return 0;
} /* cmpmul_ */

/*     **************************************************************** */
/*     *                                                              * */
/*     *                 SUBROUTINE ARYDIV                            * */
/*     *                                                              * */
/*     *                                                              * */
/*     *  Description : Returns the double precision complex number   * */
/*     *    resulting from the division of four arrays, representing  * */
/*     *    two complex numbers.  The number returned will be in one  * */
/*     *    of two different forms:  either standard scientific or as * */
/*     *    the log (base 10) of the number.                          * */
/*     *                                                              * */
/*     *  Subprograms called: CONV21, CONV12, EADD, ECPDIV, EMULT.    * */
/*     *                                                              * */
/*     **************************************************************** */
/* Subroutine */ int arydiv_(doublereal *ar, doublereal *ai, doublereal *br, 
	doublereal *bi, doublecomplex *c__, integer *l, integer *lnpfq, 
	doublereal *rmax, integer *ibit)
{
    /* System generated locals */
    doublereal d__1;
    doublecomplex z__1;

    /* Builtin functions */
    //double d_lg10(doublereal *), d_sign(doublereal *, doublereal *), pow_dd(
	  //  doublereal *, doublereal *), atan2(doublereal, doublereal), log(
	  //  doublereal);

    /* Local variables */
    static doublereal x, e1, e2, e3, n1, n2, n3, x1, x2, ae[4]	/* was [2][2] 
	    */, be[4]	/* was [2][2] */, ce[4]	/* was [2][2] */;
    static integer ii10, ir10;
    static doublereal ri10, phi, rr10, dum1, dum2;
    extern /* Subroutine */ int eadd_(doublereal *, doublereal *, doublereal *
	    , doublereal *, doublereal *, doublereal *);
    static doublecomplex cdum;
    static real dnum;
    static integer rexp;
    extern /* Subroutine */ int conv12_(doublecomplex *, doublereal *), 
	    conv21_(doublereal *, doublecomplex *), emult_(doublereal *, 
	    doublereal *, doublereal *, doublereal *, doublereal *, 
	    doublereal *), ecpdiv_(doublereal *, doublereal *, doublereal *);
    static doublereal tenmax;
    static integer itnmax;

    /* Parameter adjustments */
    ++bi;
    ++br;
    ++ai;
    ++ar;

    /* Function Body */
    rexp = *ibit / 2;
    x = rexp * (ar[*l + 1] - 2);
    rr10 = x * d_lg10(&consts_1.two) / d_lg10(&consts_1.ten);
    ir10 = (integer) rr10;
    rr10 -= ir10;
    x = rexp * (ai[*l + 1] - 2);
    ri10 = x * d_lg10(&consts_1.two) / d_lg10(&consts_1.ten);
    ii10 = (integer) ri10;
    ri10 -= ii10;
    d__1 = ar[1] * *rmax * *rmax + ar[2] * *rmax + ar[3];
    dum1 = d_sign(&d__1, &ar[-1]);
    d__1 = ai[1] * *rmax * *rmax + ai[2] * *rmax + ai[3];
    dum2 = d_sign(&d__1, &ai[-1]);
    dum1 *= pow_dd(&c_b64, &rr10);
    dum2 *= pow_dd(&c_b64, &ri10);
    z__1.r = dum1, z__1.i = dum2;
    cdum.r = z__1.r, cdum.i = z__1.i;
    conv12_(&cdum, ae);
    ae[2] += ir10;
    ae[3] += ii10;
    x = rexp * (br[*l + 1] - 2);
    rr10 = x * d_lg10(&consts_1.two) / d_lg10(&consts_1.ten);
    ir10 = (integer) rr10;
    rr10 -= ir10;
    x = rexp * (bi[*l + 1] - 2);
    ri10 = x * d_lg10(&consts_1.two) / d_lg10(&consts_1.ten);
    ii10 = (integer) ri10;
    ri10 -= ii10;
    d__1 = br[1] * *rmax * *rmax + br[2] * *rmax + br[3];
    dum1 = d_sign(&d__1, &br[-1]);
    d__1 = bi[1] * *rmax * *rmax + bi[2] * *rmax + bi[3];
    dum2 = d_sign(&d__1, &bi[-1]);
    dum1 *= pow_dd(&c_b64, &rr10);
    dum2 *= pow_dd(&c_b64, &ri10);
    z__1.r = dum1, z__1.i = dum2;
    cdum.r = z__1.r, cdum.i = z__1.i;
    conv12_(&cdum, be);
    be[2] += ir10;
    be[3] += ii10;
    ecpdiv_(ae, be, ce);
    if (*lnpfq == 0) {
	conv21_(ce, c__);
    } else {
	emult_(ce, &ce[2], ce, &ce[2], &n1, &e1);
	emult_(&ce[1], &ce[3], &ce[1], &ce[3], &n2, &e2);
	eadd_(&n1, &e1, &n2, &e2, &n3, &e3);
	n1 = ce[0];
	e1 = ce[2] - ce[3];
	x2 = ce[1];

/*     TENMAX - MAXIMUM SIZE OF EXPONENT OF 10 */
/*     THE FOLLOWING CODE CAN BE USED TO DETERMINE TENMAX, BUT IT */
/*     WILL LIKELY GENERATE AN IEEE FLOATING POINT UNDERFLOW ERROR */
/*     ON A SUN WORKSTATION.  REPLACE TENMAX WITH THE VALUE APPROPRIATE */
/*     FOR YOUR MACHINE. */

	tenmax = 320.;
	itnmax = 1;
	dnum = .1f;
L10:
	++itnmax;
	dnum *= .1;
	if (dnum > consts_1.zero) {
	    goto L10;
	}
	--itnmax;
	tenmax = (doublereal) itnmax;

	if (e1 > tenmax) {
	    x1 = tenmax;
	} else if (e1 < -tenmax) {
	    x1 = consts_1.zero;
	} else {
	    x1 = n1 * pow_dd(&consts_1.ten, &e1);
	}
	if (x2 != consts_1.zero) {
	    phi = atan2(x2, x1);
	} else {
	    phi = consts_1.zero;
	}
	d__1 = consts_1.half * (log(n3) + e3 * log(consts_1.ten));
	z__1.r = d__1, z__1.i = phi;
	c__->r = z__1.r, c__->i = z__1.i;
    }
    return 0;
} /* arydiv_ */

/*     **************************************************************** */
/*     *                                                              * */
/*     *                 SUBROUTINE EMULT                             * */
/*     *                                                              * */
/*     *                                                              * */
/*     *  Description : Takes one base and exponent and multiplies it * */
/*     *    by another numbers base and exponent to give the product  * */
/*     *    in the form of base and exponent.                         * */
/*     *                                                              * */
/*     *  Subprograms called: none                                    * */
/*     *                                                              * */
/*     **************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -