Precision improvements for user functions that return flonums

Performance: 2d-plot-area% now uses flonums internally as much as possible
This commit is contained in:
Neil Toronto 2011-11-30 11:37:07 -07:00
parent 1c9c31efd1
commit 73615de58f
3 changed files with 88 additions and 41 deletions

View File

@ -1,6 +1,7 @@
#lang racket/base
(require racket/draw racket/class racket/contract racket/match racket/math racket/list racket/string
racket/flonum
"../common/plot-device.rkt"
"../common/ticks.rkt"
"../common/contract.rkt"
@ -30,8 +31,6 @@
(define half-char-height (* 1/2 char-height))
(match-define (vector (ivl x-min x-max) (ivl y-min y-max)) bounds-rect)
(define x-size (- x-max x-min))
(define y-size (- y-max y-min))
(define x-mid (* 1/2 (+ x-min x-max)))
(define y-mid (* 1/2 (+ y-min y-max)))
@ -73,17 +72,45 @@
(cond [clipping? (vector (ivl clip-x-min clip-x-max) (ivl clip-y-min clip-y-max))]
[else bounds-rect]))
(define identity-transforms?
(and (equal? (plot-x-transform) id-transform)
(equal? (plot-y-transform) id-transform)))
;; There are three coordinate systems:
;; 1. Plot coordinates (original, user-facing coordinate system)
;; 2. View coordinates (from plot coordinates: transform for each axis)
;; 3. Device context coordinates (from view coordinates: scale to plot area)
(match-define (invertible-function fx gx) (apply-axis-transform (plot-x-transform) x-min x-max))
(match-define (invertible-function fy gy) (apply-axis-transform (plot-y-transform) y-min y-max))
(define identity-transforms?
(and (equal? (plot-x-transform) id-transform)
(equal? (plot-y-transform) id-transform)))
(define flonum-ok? (flonum-ok-for-2d? x-min x-max y-min y-max))
(when flonum-ok?
(set! x-min (exact->inexact x-min))
(set! x-max (exact->inexact x-max))
(set! y-min (exact->inexact y-min))
(set! y-max (exact->inexact y-max))
(set! x-mid (exact->inexact x-mid))
(set! y-mid (exact->inexact y-mid)))
(define plot->view
(cond [identity-transforms? (λ (v) v)]
[else (λ (v) (match-let ([(vector x y) v])
(vector (fx x) (fy y))))]))
(if flonum-ok?
(if identity-transforms?
(match-lambda
[(vector x y) (vector (exact->inexact x) (exact->inexact y))])
(match-lambda
[(vector (? rational? x) (? rational? y))
(vector (exact->inexact (fx x)) (exact->inexact (fy y)))]
[(vector x y) (vector +nan.0 +nan.0)]))
(if identity-transforms?
(match-lambda
[(vector (? rational? x) (? rational? y))
(vector (inexact->exact x) (inexact->exact y))]
[(vector x y) (vector +nan.0 +nan.0)])
(match-lambda
[(vector (? rational? x) (? rational? y))
(vector (inexact->exact (fx x)) (inexact->exact (fy y)))]
[(vector x y) (vector +nan.0 +nan.0)]))))
(define view->dc #f)
(define (plot->dc v) (view->dc (plot->view v)))
@ -101,10 +128,17 @@
(define area-y-max (- dc-y-size bottom))
(define area-per-view-x (/ (- area-x-max area-x-min) view-x-size))
(define area-per-view-y (/ (- area-y-max area-y-min) view-y-size))
(λ (v)
(match-define (vector x y) v)
(vector (+ area-x-min (* (- x x-min) area-per-view-x))
(- area-y-max (* (- y y-min) area-per-view-y)))))
(if flonum-ok?
(let-map
(area-x-min area-per-view-x x-min area-y-max y-min area-per-view-y) exact->inexact
(λ (v)
(match-define (vector x y) v)
(vector (fl+ area-x-min (fl* (fl- x x-min) area-per-view-x))
(fl- area-y-max (fl* (fl- y y-min) area-per-view-y)))))
(λ (v)
(match-define (vector x y) v)
(vector (+ area-x-min (* (- x x-min) area-per-view-x))
(- area-y-max (* (- y y-min) area-per-view-y))))))
(define init-top-margin
(cond [(and (plot-decorations?) (plot-title)) (* 3/2 char-height)]

View File

@ -115,27 +115,36 @@
(define flonum-ok? (flonum-ok-for-3d? x-min x-max y-min y-max z-min z-max))
(define plot->norm
(cond [identity-transforms?
(cond [flonum-ok?
(let-map
(x-mid y-mid z-mid x-size y-size z-size) exact->inexact
(λ (v)
(match-define (vector x y z) v)
(vector (fl/ (fl- (exact->inexact x) x-mid) x-size)
(fl/ (fl- (exact->inexact y) y-mid) y-size)
(fl/ (fl- (exact->inexact z) z-mid) z-size))))]
[else
(λ (v)
(match-define (vector x y z) v)
(vector (exact->inexact (/ (- x x-mid) x-size))
(exact->inexact (/ (- y y-mid) y-size))
(exact->inexact (/ (- z z-mid) z-size))))])]
[else
(λ (v)
(match-define (vector x y z) v)
(vector (exact->inexact (/ (- (fx x) x-mid) x-size))
(exact->inexact (/ (- (fy y) y-mid) y-size))
(exact->inexact (/ (- (fz z) z-mid) z-size))))]))
(if flonum-ok?
(let-map
(x-mid y-mid z-mid x-size y-size z-size) exact->inexact
(if identity-transforms?
(match-lambda
[(vector x y z)
(vector (fl/ (fl- (exact->inexact x) x-mid) x-size)
(fl/ (fl- (exact->inexact y) y-mid) y-size)
(fl/ (fl- (exact->inexact z) z-mid) z-size))])
(match-lambda
[(vector (? rational? x) (? rational? y) (? rational? z))
(vector (fl/ (fl- (exact->inexact (fx x)) x-mid) x-size)
(fl/ (fl- (exact->inexact (fy y)) y-mid) y-size)
(fl/ (fl- (exact->inexact (fz z)) z-mid) z-size))]
[(vector x y z) (vector +nan.0 +nan.0 +nan.0)])))
(if identity-transforms?
(match-lambda
[(vector (? rational? x) (? rational? y) (? rational? z))
(vector (exact->inexact (/ (- (inexact->exact x) x-mid) x-size))
(exact->inexact (/ (- (inexact->exact y) y-mid) y-size))
(exact->inexact (/ (- (inexact->exact z) z-mid) z-size)))]
[(vector x y z)
(vector +nan.0 +nan.0 +nan.0)])
(match-lambda
[(vector (? rational? x) (? rational? y) (? rational? z))
(vector (exact->inexact (/ (- (inexact->exact (fx x)) x-mid) x-size))
(exact->inexact (/ (- (inexact->exact (fy y)) y-mid) y-size))
(exact->inexact (/ (- (inexact->exact (fz z)) z-mid) z-size)))]
[(vector x y z)
(vector +nan.0 +nan.0 +nan.0)]))))
(define rotate-theta-matrix (m3-rotate-z theta))
(define rotate-rho-matrix (m3-rotate-x rho))

View File

@ -10,6 +10,14 @@
#:x-min +min.0 #:x-max (flstep +min.0 1000)
#:y-min 0 #:y-max 1 #:z-min 0 #:z-max 1)
;; this should go all the way from the bottom to the top
(plot (function exact->inexact (flstep 0.0 -1) (flstep 0.0 2)))
;; this should go all the way from the bottom to the top
(plot3d (surface3d (λ (x y) (exact->inexact x))
(flstep 0.0 -1) (flstep 0.0 2)
(flstep 0.0 -1) (flstep 0.0 2)))
(plot-x-label #f)
(plot-y-label #f)
@ -31,8 +39,8 @@
(list (format "[~a,~a] × [~a,~a]"
(extreme-real->string x-min) (extreme-real->string x-max)
(extreme-real->string y-min) (extreme-real->string y-max))
(time (plot (lines (list (vector (inexact->exact x-min) (inexact->exact y-min))
(vector (inexact->exact x-max) (inexact->exact y-max))))))))
(time (plot (lines (list (vector x-min y-min)
(vector x-max y-max)))))))
(set! num-2d (+ 1 num-2d))))
(printf "Total 2D plots: ~a~n" num-2d)
@ -54,12 +62,8 @@
(extreme-real->string x-min) (extreme-real->string x-max)
(extreme-real->string y-min) (extreme-real->string y-max)
(extreme-real->string z-min) (extreme-real->string z-max))
(time (plot3d (lines3d (list (vector (inexact->exact x-min)
(inexact->exact y-min)
(inexact->exact z-min))
(vector (inexact->exact x-max)
(inexact->exact y-max)
(inexact->exact z-max))))))))
(time (plot3d (lines3d (list (vector x-min y-min z-min)
(vector x-max y-max z-max)))))))
(set! num-3d (+ 1 num-3d))))
(printf "Total plots: ~a~n" num-3d)