Skip to content

Commit cd233ee

Browse files
authored
Merge pull request #1275 from herbie-fp/codex/add-fabs-support-to-taylor-expander
Add fabs support to Taylor series expander
2 parents ecc905e + 21c4a3f commit cd233ee

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

src/core/taylor.rkt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@
165165
[`(/ ,num ,den) (taylor-quotient (recurse num) (recurse den))]
166166
[`(sqrt ,arg) (taylor-sqrt var (recurse arg))]
167167
[`(cbrt ,arg) (taylor-cbrt var (recurse arg))]
168+
[`(fabs ,arg) (or (taylor-fabs var (recurse arg)) (taylor-exact brf))]
168169
[`(exp ,arg)
169170
(define arg* (normalize-series (recurse arg)))
170171
(if (positive? (series-offset arg*))
@@ -391,6 +392,24 @@
391392
`(* ,(f a) ,(f b) ,(f c))))
392393
(* 3 ,(f 0) ,(f 0)))]))))
393394

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+
394413
(define (taylor-pow coeffs n)
395414
;(-> term? number? term?)
396415
(match n ;; Russian peasant multiplication
@@ -576,4 +595,6 @@
576595
(check-equal? (coeffs '(cbrt (+ 1 x))) '(1 1/3 -1/9 5/81 -10/243 22/729 -154/6561))
577596
(check-equal? (coeffs '(sqrt x)) '((sqrt x) 0 0 0 0 0 0))
578597
(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

Comments
 (0)