|
165 | 165 | [`(/ ,num ,den) (taylor-quotient (recurse num) (recurse den))] |
166 | 166 | [`(sqrt ,arg) (taylor-sqrt var (recurse arg))] |
167 | 167 | [`(cbrt ,arg) (taylor-cbrt var (recurse arg))] |
| 168 | + [`(fabs ,arg) (or (taylor-fabs var (recurse arg)) (taylor-exact brf))] |
168 | 169 | [`(exp ,arg) |
169 | 170 | (define arg* (normalize-series (recurse arg))) |
170 | 171 | (if (positive? (series-offset arg*)) |
|
391 | 392 | `(* ,(f a) ,(f b) ,(f c)))) |
392 | 393 | (* 3 ,(f 0) ,(f 0)))])))) |
393 | 394 |
|
| 395 | +(define (taylor-fabs var term) |
| 396 | + (define normalized (normalize-series term)) |
| 397 | + (define offset (series-offset normalized)) |
| 398 | + (define a0 (deref (series-ref normalized 0))) |
| 399 | + (cond |
| 400 | + [(or (not (number? a0)) (zero? a0)) #f] |
| 401 | + [(and (even? offset) (negative? a0)) (taylor-negate normalized)] |
| 402 | + [(and (even? offset) (positive? a0)) normalized] |
| 403 | + [(odd? offset) |
| 404 | + (define scale-factor (adder `(* (fabs ,var) ,(if (negative? a0) -1 1)))) |
| 405 | + (define new-offset (add1 offset)) |
| 406 | + (make-series new-offset |
| 407 | + (λ (f n) |
| 408 | + (if (zero? n) |
| 409 | + scale-factor |
| 410 | + (series-ref normalized (+ n (- new-offset offset))))))] |
| 411 | + [else #f])) |
| 412 | + |
394 | 413 | (define (taylor-pow coeffs n) |
395 | 414 | ;(-> term? number? term?) |
396 | 415 | (match n ;; Russian peasant multiplication |
|
576 | 595 | (check-equal? (coeffs '(cbrt (+ 1 x))) '(1 1/3 -1/9 5/81 -10/243 22/729 -154/6561)) |
577 | 596 | (check-equal? (coeffs '(sqrt x)) '((sqrt x) 0 0 0 0 0 0)) |
578 | 597 | (check-equal? (coeffs '(cbrt x)) '((cbrt x) 0 0 0 0 0 0)) |
579 | | - (check-equal? (coeffs '(cbrt (* x x))) '((pow x 2/3) 0 0 0 0 0 0))) |
| 598 | + (check-equal? (coeffs '(cbrt (* x x))) '((pow x 2/3) 0 0 0 0 0 0)) |
| 599 | + (check-equal? (coeffs '(fabs (+ 2 x))) '(2 1 0 0 0 0 0)) |
| 600 | + (check-equal? (coeffs '(fabs (+ -2 x))) '(2 -1 0 0 0 0 0))) |
0 commit comments