| | 534 | |
| | 535 | ;; Carlson's Rc function. |
| | 536 | ;; |
| | 537 | ;; Some interesting identities: |
| | 538 | ;; |
| | 539 | ;; log(x) = (x-1)*rc(((1+x)/2)^2, x), x > 0 |
| | 540 | ;; asin(x) = x * rc(1-x^2, 1), |x|<= 1 |
| | 541 | ;; acos(x) = sqrt(1-x^2)*rc(x^2,1), 0 <= x <=1 |
| | 542 | ;; atan(x) = x * rc(1,1+x^2) |
| | 543 | ;; asinh(x) = x * rc(1+x^2,1) |
| | 544 | ;; acosh(x) = sqrt(x^2-1) * rc(x^2,1), x >= 1 |
| | 545 | ;; atanh(x) = x * rc(1,1-x^2), |x|<=1 |
| | 546 | ;; |
| | 547 | |
| | 548 | (defun carlson-rc (x y) |
| | 549 | "Compute Carlson's Rc function: |
| | 550 | |
| | 551 | Rc(x,y) = integrate(1/2*(t+x)^(-1/2)*(t+y)^(-1), t, 0, inf)" |
| | 552 | (let* ((precision (float-contagion x y)) |
| | 553 | (yn (apply-contagion y precision)) |
| | 554 | (x (apply-contagion x precision)) |
| | 555 | xn z w a an pwr4 n epslon lambda sn s) |
| | 556 | (cond ((and (zerop (imagpart yn)) |
| | 557 | (minusp (realpart yn))) |
| | 558 | (setf xn (- x y)) |
| | 559 | (setf yn (- yn)) |
| | 560 | (setf z yn) |
| | 561 | (setf w (sqrt (/ x xn)))) |
| | 562 | (t |
| | 563 | (setf xn x) |
| | 564 | (setf z yn) |
| | 565 | (setf w 1))) |
| | 566 | (setf a (/ (+ xn yn yn) 3)) |
| | 567 | (setf epslon (/ (abs (- a xn)) (errtol x y))) |
| | 568 | (setf an a) |
| | 569 | (setf pwr4 1) |
| | 570 | (setf n 0) |
| | 571 | (loop while (> (* epslon pwr4) (abs an)) |
| | 572 | do |
| | 573 | (setf pwr4 (/ pwr4 4)) |
| | 574 | (setf lambda (+ (* 2 (sqrt xn) (sqrt yn)) yn)) |
| | 575 | (setf an (/ (+ an lambda) 4)) |
| | 576 | (setf xn (/ (+ xn lambda) 4)) |
| | 577 | (setf yn (/ (+ yn lambda) 4)) |
| | 578 | (incf n)) |
| | 579 | ;; c2=3/10,c3=1/7,c4=3/8,c5=9/22,c6=159/208,c7=9/8 |
| | 580 | (setf sn (/ (* pwr4 (- z a)) an)) |
| | 581 | (setf s (* sn sn (+ 3/10 |
| | 582 | (* sn (+ 1/7 |
| | 583 | (* sn (+ 3/8 |
| | 584 | (* sn (+ 9/22 |
| | 585 | (* sn (+ 159/208 |
| | 586 | (* sn 9/8)))))))))))) |
| | 587 | (/ (* w (+ 1 s)) |
| | 588 | (sqrt an)))) |
| | 589 | |
| | 590 | (defun carlson-rj1 (x y z p) |
| | 591 | (let* ((xn x) |
| | 592 | (yn y) |
| | 593 | (zn z) |
| | 594 | (pn p) |
| | 595 | (en (* (- pn xn) |
| | 596 | (- pn yn) |
| | 597 | (- pn zn))) |
| | 598 | (sigma 0) |
| | 599 | (power4 1) |
| | 600 | (k 0) |
| | 601 | (a (/ (+ xn yn zn pn pn) 5)) |
| | 602 | (epslon (/ (max (abs (- a xn)) |
| | 603 | (abs (- a yn)) |
| | 604 | (abs (- a zn)) |
| | 605 | (abs (- a pn))) |
| | 606 | (errtol x y z p))) |
| | 607 | (an a) |
| | 608 | xnroot ynroot znroot pnroot lam dn) |
| | 609 | (loop while (> (* power4 epslon) (abs an)) |
| | 610 | do |
| | 611 | (setf xnroot (sqrt xn)) |
| | 612 | (setf ynroot (sqrt yn)) |
| | 613 | (setf znroot (sqrt zn)) |
| | 614 | (setf pnroot (sqrt pn)) |
| | 615 | (setf lam (+ (* xnroot ynroot) |
| | 616 | (* xnroot znroot) |
| | 617 | (* ynroot znroot))) |
| | 618 | (setf dn (* (+ pnroot xnroot) |
| | 619 | (+ pnroot ynroot) |
| | 620 | (+ pnroot znroot))) |
| | 621 | (setf sigma (+ sigma |
| | 622 | (/ (* power4 |
| | 623 | (carlson-rc 1 (+ 1 (/ en (* dn dn))))) |
| | 624 | dn))) |
| | 625 | (setf power4 (* power4 1/4)) |
| | 626 | (setf en (/ en 64)) |
| | 627 | (setf xn (* (+ xn lam) 1/4)) |
| | 628 | (setf yn (* (+ yn lam) 1/4)) |
| | 629 | (setf zn (* (+ zn lam) 1/4)) |
| | 630 | (setf pn (* (+ pn lam) 1/4)) |
| | 631 | (setf an (* (+ an lam) 1/4)) |
| | 632 | (incf k)) |
| | 633 | (let* ((xndev (/ (* (- a x) power4) an)) |
| | 634 | (yndev (/ (* (- a y) power4) an)) |
| | 635 | (zndev (/ (* (- a z) power4) an)) |
| | 636 | (pndev (* -0.5 (+ xndev yndev zndev))) |
| | 637 | (ee2 (+ (* xndev yndev) |
| | 638 | (* xndev zndev) |
| | 639 | (* yndev zndev) |
| | 640 | (* -3 pndev pndev))) |
| | 641 | (ee3 (+ (* xndev yndev zndev) |
| | 642 | (* 2 ee2 pndev) |
| | 643 | (* 4 pndev pndev pndev))) |
| | 644 | (ee4 (* (+ (* 2 xndev yndev zndev) |
| | 645 | (* ee2 pndev) |
| | 646 | (* 3 pndev pndev pndev)) |
| | 647 | pndev)) |
| | 648 | (ee5 (* xndev yndev zndev pndev pndev)) |
| | 649 | (s (+ 1 |
| | 650 | (* -3/14 ee2) |
| | 651 | (* 1/6 ee3) |
| | 652 | (* 9/88 ee2 ee2) |
| | 653 | (* -3/22 ee4) |
| | 654 | (* -9/52 ee2 ee3) |
| | 655 | (* 3/26 ee5) |
| | 656 | (* -1/16 ee2 ee2 ee2) |
| | 657 | (* 3/10 ee3 ee3) |
| | 658 | (* 3/20 ee2 ee4) |
| | 659 | (* 45/272 ee2 ee2 ee3) |
| | 660 | (* -9/68 (+ (* ee2 ee5) (* ee3 ee4)))))) |
| | 661 | (+ (* 6 sigma) |
| | 662 | (/ (* power4 s) |
| | 663 | (sqrt (* an an an))))))) |
| | 664 | |
| | 665 | (defun carlson-rj (x y z p) |
| | 666 | "Compute Carlson's Rj function: |
| | 667 | |
| | 668 | Rj(x,y,z,p) = integrate(3/2*(t+x)^(-1/2)*(t+y)^(-1/2)*(t+z)^(-1/2)*(t+p)^(-1), t, 0, inf)" |
| | 669 | (let* ((precision (float-contagion x y z p)) |
| | 670 | (xn (apply-contagion x precision)) |
| | 671 | (yn (apply-contagion y precision)) |
| | 672 | (zn (apply-contagion z precision)) |
| | 673 | (p (apply-contagion p precision)) |
| | 674 | (qn (- p))) |
| | 675 | (cond ((and (and (zerop (imagpart xn)) (>= (realpart xn) 0)) |
| | 676 | (and (zerop (imagpart yn)) (>= (realpart yn) 0)) |
| | 677 | (and (zerop (imagpart zn)) (>= (realpart zn) 0)) |
| | 678 | (and (zerop (imagpart qn)) (> (realpart qn) 0))) |
| | 679 | (destructuring-bind (xn yn zn) |
| | 680 | (sort (list xn yn zn) #'<) |
| | 681 | (let* ((pn (+ yn (* (- zn yn) (/ (- yn xn) (+ yn qn))))) |
| | 682 | (s (- (* (- pn yn) (carlson-rj1 xn yn zn pn)) |
| | 683 | (* 3 (carlson-rf xn yn zn))))) |
| | 684 | (setf s (+ s (* 3 (sqrt (/ (* xn yn zn) |
| | 685 | (+ (* xn zn) (* pn qn)))) |
| | 686 | (carlson-rc (+ (* xn zn) (* pn qn)) (* pn qn))))) |
| | 687 | (/ s (+ yn qn))))) |
| | 688 | (t |
| | 689 | (carlson-rj1 x y z p))))) |
| | 690 | |
| | 691 | ;; Elliptic integral of the third kind: |
| | 692 | ;; |
| | 693 | ;; (A&S 17.2.14) |
| | 694 | ;; |
| | 695 | ;; PI(n; phi|m) = integrate(1/sqrt(1-m*sin(x)^2)/(1-n*sin(x)^2), x, 0, phi) |
| | 696 | ;; |
| | 697 | (defun elliptic-pi (n phi m) |
| | 698 | "Compute elliptic integral of the third kind: |
| | 699 | |
| | 700 | PI(n; phi|m) = integrate(1/sqrt(1-m*sin(x)^2)/(1-n*sin(x)^2), x, 0, phi)" |
| | 701 | ;; Note: Carlson's DRJ has n defined as the negative of the n given |
| | 702 | ;; in A&S. |
| | 703 | (let* ((precision (float-contagion n phi m)) |
| | 704 | (n (apply-contagion n precision)) |
| | 705 | (phi (apply-contagion phi precision)) |
| | 706 | (m (apply-contagion m precision)) |
| | 707 | (nn (- n)) |
| | 708 | (sin-phi (sin phi)) |
| | 709 | (cos-phi (cos phi)) |
| | 710 | (k (sqrt m)) |
| | 711 | (k2sin (* (- 1 (* k sin-phi)) |
| | 712 | (+ 1 (* k sin-phi))))) |
| | 713 | (- (* sin-phi (carlson-rf (expt cos-phi 2) k2sin 1)) |
| | 714 | (* (/ nn 3) (expt sin-phi 3) |
| | 715 | (carlson-rj (expt cos-phi 2) k2sin 1 |
| | 716 | (+ 1 (* nn (expt sin-phi 2)))))))) |