1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancements. ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;; (c) Copyright 1982 Massachusetts Institute of Technology ;;;
9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12 (macsyma-module logarc
)
14 ;;; Logarc and Halfangles
16 (defmfun $logarc
(exp)
17 (cond ((atom exp
) exp
)
18 ((arcp (caar exp
)) (logarc (caar exp
) ($logarc
(cadr exp
))))
19 ((eq (caar exp
) '%atan2
)
20 (logarc '%atan2
(list ($logarc
(second exp
)) ($logarc
(third exp
)))))
21 (t (recur-apply #'$logarc exp
))))
24 ;; Gives the logarithmic form of arc trig and hyperbolic functions
26 ;; -%i * log(x + %i*sqrt(1-x^2))
27 (mul -
1 '$%i
(take '(%log
) (add x
(mul '$%i
(root (sub 1 (power x
2)) 2))))))
29 ;; -%i * log(sqrt(1-x^2)+%i*x)
30 (mul -
1 '$%i
(take '(%log
) (add (mul '$%i x
) (root (sub 1 (power x
2)) 2)))))
32 ;; (log(1 + %i*x) - log(1 - %i*x)) /(2 %i)
33 (div (sub (take '(%log
) (add 1 (mul '$%i x
))) (take '(%log
) (sub 1 (mul '$%i x
))))
36 ;; atan2(y,x) = -%i*log((x + %i*y)/sqrt(x^2+y^2))
37 (destructuring-bind (y x
)
40 (take '(%log
) (div (add x
(mul '$%i y
))
41 (root (add (mul x x
) (mul y y
)) 2))))))
44 (take '(%log
) (add x
(root (add 1 (power x
2)) 2))))
46 ;; log(x+sqrt(x-1)*sqrt(x+1))
47 (take '(%log
) (add x
(mul (root (add x -
1) 2) (root (add x
1) 2)))))
49 ;; (log(x+1)-log(1-x))/2
50 (div (sub (take '(%log
) (add 1 x
)) (take '(%log
) (sub 1 x
))) 2))
51 ((member f
'(%asec %acsc %acot %asech %acsch %acoth
) :test
#'eq
)
52 ;; asec(x) = acos(1/x), and etc.
53 (logarc (zl-get (zl-get (get f
'$inverse
) 'recip
) '$inverse
) (inv x
)))
54 (t (merror "LOGARC: unrecognized argument: ~M" f
))))
56 ;; Conditionally apply a logarc transformation to operators that either have the
57 ;; arcp property or that are %atan2 expressions but are *not* members of the list `l`.
58 ;; We could blend this functionality into $logarc, but I'm not sure there is much
60 (defun partial-logarc (e l
)
62 ((and (arcp (caar e
)) (not (member (caar e
) l
)))
63 (logarc (caar e
) (partial-logarc (cadr e
) l
)))
64 ((eq (caar e
) '%atan2
)
65 (logarc '%atan2
(list (partial-logarc (second e
) l
)
66 (partial-logarc (third e
) l
))))
67 (t (recur-apply #'(lambda (q) (partial-logarc q l
)) e
))))
69 (defun halfangle (f a
)
72 (equal (caddr (cadr a
)) 2)
73 (halfangleaux f
(mul 2 a
))))
75 (defun halfangleaux (f a
) ;; f=function; a=twice argument
76 (let ((sw (member f
'(%cos %cot %coth %cosh
) :test
#'eq
)))
77 (cond ((member f
'(%sin %cos
) :test
#'eq
)
78 (mul (halfangleaux-factor f a
)
79 (power (div (add 1 (porm sw
(take '(%cos
) a
))) 2) 1//2)))
80 ((member f
'(%tan %cot
) :test
#'eq
)
81 (div (add 1 (porm sw
(take '(%cos
) a
))) (take '(%sin
) a
)))
82 ((member f
'(%sinh %cosh
) :test
#'eq
)
83 (mul (halfangleaux-factor f a
)
84 (power (div (add (take '(%cosh
) a
) (porm sw
1)) 2) 1//2)))
85 ((member f
'(%tanh %coth
) :test
#'eq
)
86 (div (add (take '(%cosh
) a
) (porm sw
1)) (take '(%sinh
) a
)))
87 ((member f
'(%sec %csc %sech %csch
) :test
#'eq
)
88 (inv (halfangleaux (get f
'recip
) a
))))))
90 (defun halfangleaux-factor (f a
)
92 ((member f
'(%sin %cos
))
93 (let ((arg (div (if (eq f
'%sin
)
95 (add ($realpart a
) '$%pi
))
98 (power -
1 (simplify (list '($floor
) arg
)))
102 (power -
1 (add (simplify (list '($floor
) arg
))
103 (simplify (list '($floor
) (mul -
1 arg
))))))
104 (simplify (list '($unit_step
) (mul -
1 ($imagpart a
)))))))))
105 ((member f
'(%sinh %cosh
))
106 (let ((arg (div (add ($imagpart a
) '$%pi
) (mul 2 '$%pi
)))
107 (fac (if (eq f
'%sinh
)
108 (div (power (power a
2) (div 1 2)) a
)
111 (power -
1 (simplify (list '($floor
) arg
)))
115 (power -
1 (add (simplify (list '($floor
) arg
))
116 (simplify (list '($floor
) (mul -
1 arg
))))))
117 (simplify (list '($unit_step
) ($realpart a
))))))))