racket/collects/plot/tests/low-level-tests.rkt
Neil Toronto 365ee2c70d 1d, 2d and 3d function renderers no longer sample outside the function's bounds
This makes it more efficient to plot piecewise functions by drawing each piece with one renderer, and possible to plot functions with discontinuities by using a renderer to draw each continuous piece.
2012-05-25 10:40:05 +09:00

357 lines
13 KiB
Racket
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#lang racket
(require rackunit racket/date
plot plot/utils
plot/common/utils
(only-in plot/common/math
vector-andmap
vector-ormap)
(only-in plot/common/date-time
utc-seconds-round-year
utc-seconds-round-month
seconds-per-minute
seconds-per-hour
seconds-per-day
seconds-per-week)
(only-in plot/common/format
int-str->e-str frac-str->e-str)
plot/common/worker-thread)
(check-equal? (linear-seq 0 1 2 #:start? #t #:end? #t) '(0 1))
(check-equal? (linear-seq 0 1 2 #:start? #t #:end? #f) '(0 2/3))
(check-equal? (linear-seq 0 1 2 #:start? #f #:end? #t) '(1/3 1))
(check-equal? (linear-seq 0 1 2 #:start? #f #:end? #f) '(1/4 3/4))
(check-exn exn:fail:contract?
(λ () (vector-field (λ (v [z 0]) v) -4 4 -4 4))
"Exception should be 'two of the clauses in the or/c might both match' or similar")
;; ===================================================================================================
;; Formatting
(check-equal? (int-str->e-str "") "0")
(check-equal? (int-str->e-str "0") "0")
(check-equal? (int-str->e-str "10") "1×10\u00b9")
(check-equal? (frac-str->e-str "") "0")
(check-equal? (frac-str->e-str "0") "0")
(check-equal? (frac-str->e-str "00") "0")
(check-equal? (frac-str->e-str "1") "1×10\u207b\u00b9")
(check-equal? (frac-str->e-str "01") "1×10\u207b\u00b2")
;; ===================================================================================================
;; Date rounding
(check-equal? (utc-seconds-round-year (find-seconds 0 0 12 2 7 1970 #f))
(find-seconds 0 0 0 1 1 1970 #f))
(check-equal? (utc-seconds-round-year (find-seconds 0 0 13 2 7 1970 #f))
(find-seconds 0 0 0 1 1 1971 #f))
;; A leap year's middle is a half day earlier on the calendar:
(check-equal? (utc-seconds-round-year (find-seconds 0 0 0 2 7 1976 #f))
(find-seconds 0 0 0 1 1 1976 #f))
(check-equal? (utc-seconds-round-year (find-seconds 0 0 1 2 7 1976 #f))
(find-seconds 0 0 0 1 1 1977 #f))
(check-equal? (utc-seconds-round-month (find-seconds 0 0 0 16 1 2010 #f))
(find-seconds 0 0 0 1 1 2010 #f))
(check-equal? (utc-seconds-round-month (find-seconds 0 0 0 17 1 2010 #f))
(find-seconds 0 0 0 1 2 2010 #f))
(check-equal? (utc-seconds-round-month (find-seconds 0 0 12 16 1 2010 #f))
(find-seconds 0 0 0 1 1 2010 #f))
(check-equal? (utc-seconds-round-month (find-seconds 0 0 13 16 1 2010 #f))
(find-seconds 0 0 0 1 2 2010 #f))
(check-equal? (utc-seconds-round-month (find-seconds 0 0 0 16 12 2010 #f))
(find-seconds 0 0 0 1 12 2010 #f))
(check-equal? (utc-seconds-round-month (find-seconds 0 0 0 17 12 2010 #f))
(find-seconds 0 0 0 1 1 2011 #f))
;; ===================================================================================================
;; Time conversion
(check-equal? (seconds->plot-time 0) (plot-time 0 0 0 0))
(check-equal? (seconds->plot-time #e59.999999) (plot-time #e59.999999 0 0 0))
(check-equal? (seconds->plot-time 60) (plot-time 0 1 0 0))
(check-equal? (seconds->plot-time #e60.000001) (plot-time #e0.000001 1 0 0))
(check-equal? (seconds->plot-time #e119.999999) (plot-time #e59.999999 1 0 0))
(check-equal? (seconds->plot-time 120) (plot-time 0 2 0 0))
(check-equal? (seconds->plot-time #e120.000001) (plot-time #e0.000001 2 0 0))
(check-equal? (seconds->plot-time 3599) (plot-time 59 59 0 0))
(check-equal? (seconds->plot-time 3600) (plot-time 0 0 1 0))
(check-equal? (seconds->plot-time 3601) (plot-time 1 0 1 0))
(check-equal? (seconds->plot-time (- seconds-per-day 1)) (plot-time 59 59 23 0))
(check-equal? (seconds->plot-time seconds-per-day) (plot-time 0 0 0 1))
(check-equal? (seconds->plot-time (- seconds-per-day)) (plot-time 0 0 0 -1))
(check-equal? (seconds->plot-time (- (- seconds-per-day) 1)) (plot-time 59 59 23 -2))
(define sec-secs (sequence->list (in-range -60 61 #e0.571123)))
(define min-secs (sequence->list (in-range (- seconds-per-hour) (+ seconds-per-hour 1)
(* #e0.571123 seconds-per-minute))))
(define hour-secs (sequence->list (in-range (- seconds-per-day) (+ seconds-per-day 1)
(* #e0.571123 seconds-per-hour))))
(define day-secs (sequence->list (in-range (- seconds-per-week) (+ seconds-per-week 1)
(* #e0.571123 seconds-per-day))))
(check-equal? (map (compose plot-time->seconds seconds->plot-time) sec-secs) sec-secs)
(check-equal? (map (compose plot-time->seconds seconds->plot-time) min-secs) min-secs)
(check-equal? (map (compose plot-time->seconds seconds->plot-time) hour-secs) hour-secs)
(check-equal? (map (compose plot-time->seconds seconds->plot-time) day-secs) day-secs)
;; ===================================================================================================
;; Intervals
(check-false (ivl-rational? (ivl #f #f)))
(check-false (ivl-rational? (ivl +nan.0 +nan.0)))
(check-true (ivl-empty? (ivl-meet empty-ivl (ivl 0 3))))
;;; ivl-meet (similar to an intersection)
;; All specified
(check-true (ivl-empty? (ivl-meet (ivl 0 1) (ivl 2 3))))
(check-equal? (ivl-meet (ivl 0 2) (ivl 1 3)) (ivl 1 2))
(check-equal? (ivl-meet (ivl 0 3) (ivl 1 2)) (ivl 1 2))
;; One not specified
;; <--- 1 2 -- 3
(check-true (ivl-empty? (ivl-meet (ivl #f 1) (ivl 2 3))))
;; 0 -- 1 2 --->
(check-true (ivl-empty? (ivl-meet (ivl 0 1) (ivl 2 #f))))
;; <-------- 2
;; 1 ------- 3
(check-equal? (ivl-meet (ivl #f 2) (ivl 1 3)) (ivl 1 2))
;; 2 --->
;; 0 ------------ 3
(check-equal? (ivl-meet (ivl 2 #f) (ivl 0 3)) (ivl 2 3))
;; <------------- 3
;; 1 -- 2
(check-equal? (ivl-meet (ivl #f 3) (ivl 1 2)) (ivl 1 2))
;; 0 ------------->
;; 1 -- 2
(check-equal? (ivl-meet (ivl 0 #f) (ivl 1 2)) (ivl 1 2))
;; Two not specified
;; <--- 1 2 --->
(check-true (ivl-empty? (ivl-meet (ivl #f 1) (ivl 2 #f))))
;; <-------------->
;; 1 -- 2
(check-equal? (ivl-meet (ivl #f #f) (ivl 1 2)) (ivl 1 2))
;; 1 -------->
;; <-------- 2
(check-equal? (ivl-meet (ivl 1 #f) (ivl #f 2)) (ivl 1 2))
;; <-------- 2
;; <------------- 3
(check-equal? (ivl-meet (ivl #f 2) (ivl #f 3)) (ivl #f 2))
;; 0 ------------->
;; 1 -------->
(check-equal? (ivl-meet (ivl 0 #f) (ivl 1 #f)) (ivl 1 #f))
;; Three not specified
;; <-------------->
;; 1 -------->
(check-equal? (ivl-meet (ivl #f #f) (ivl 1 #f)) (ivl 1 #f))
;; <-------------->
;; <-------- 2
(check-equal? (ivl-meet (ivl #f #f) (ivl #f 2)) (ivl #f 2))
;; Four not specified
(check-equal? (ivl-meet (ivl #f #f) (ivl #f #f)) (ivl #f #f))
;; One infinite
;; <--- 1 2 -- 3
(check-true (ivl-empty? (ivl-meet (ivl -inf.0 1) (ivl 2 3))))
;; 0 -- 1 2 --->
(check-true (ivl-empty? (ivl-meet (ivl 0 1) (ivl 2 +inf.0))))
;; <-------- 2
;; 1 ------- 3
(check-equal? (ivl-meet (ivl -inf.0 2) (ivl 1 3)) (ivl 1 2))
;; 2 --->
;; 0 ------------ 3
(check-equal? (ivl-meet (ivl 2 +inf.0) (ivl 0 3)) (ivl 2 3))
;; <------------- 3
;; 1 -- 2
(check-equal? (ivl-meet (ivl -inf.0 3) (ivl 1 2)) (ivl 1 2))
;; 0 ------------->
;; 1 -- 2
(check-equal? (ivl-meet (ivl 0 +inf.0) (ivl 1 2)) (ivl 1 2))
;; Two infinite
;; <--- 1 2 --->
(check-true (ivl-empty? (ivl-meet (ivl -inf.0 1) (ivl 2 +inf.0))))
;; <-------------->
;; 1 -- 2
(check-equal? (ivl-meet (ivl -inf.0 +inf.0) (ivl 1 2)) (ivl 1 2))
;; 1 -------->
;; <-------- 2
(check-equal? (ivl-meet (ivl 1 +inf.0) (ivl -inf.0 2)) (ivl 1 2))
;; <-------- 2
;; <------------- 3
(check-equal? (ivl-meet (ivl -inf.0 2) (ivl -inf.0 3)) (ivl -inf.0 2))
;; 0 ------------->
;; 1 -------->
(check-equal? (ivl-meet (ivl 0 +inf.0) (ivl 1 +inf.0)) (ivl 1 +inf.0))
;; Three infinite
;; <-------------->
;; 1 -------->
(check-equal? (ivl-meet (ivl -inf.0 +inf.0) (ivl 1 +inf.0)) (ivl 1 +inf.0))
;; <-------------->
;; <-------- 2
(check-equal? (ivl-meet (ivl -inf.0 +inf.0) (ivl -inf.0 2)) (ivl -inf.0 2))
;; Four infinite
(check-equal? (ivl-meet (ivl -inf.0 +inf.0) (ivl -inf.0 +inf.0)) (ivl -inf.0 +inf.0))
;;; ivl-join (similar to a union)
(check-true (ivl-empty? (ivl-join empty-ivl empty-ivl)))
(check-equal? (ivl-join empty-ivl (ivl 0 3)) (ivl 0 3))
;; All specified
(check-equal? (ivl-join (ivl 0 1) (ivl 2 3)) (ivl 0 3))
(check-equal? (ivl-join (ivl 0 2) (ivl 1 3)) (ivl 0 3))
(check-equal? (ivl-join (ivl 0 3) (ivl 1 2)) (ivl 0 3))
;; One not specified
;; <--- 1 2 -- 3
(check-equal? (ivl-join (ivl #f 1) (ivl 2 3)) (ivl 2 3))
;; 0 -- 1 2 --->
(check-equal? (ivl-join (ivl 0 1) (ivl 2 #f)) (ivl 0 1))
;; <-------- 2
;; 1 ------- 3
(check-equal? (ivl-join (ivl #f 2) (ivl 1 3)) (ivl 1 3))
;; 2 --->
;; 0 ------------ 3
(check-equal? (ivl-join (ivl 2 #f) (ivl 0 3)) (ivl 0 3))
;; <------------- 3
;; 1 -- 2
(check-equal? (ivl-join (ivl #f 3) (ivl 1 2)) (ivl 1 3))
;; 0 ------------->
;; 1 -- 2
(check-equal? (ivl-join (ivl 0 #f) (ivl 1 2)) (ivl 0 2))
;; Two not specified
;; <--- 1 2 --->
(check-equal? (ivl-join (ivl #f 1) (ivl 2 #f)) (ivl 1 2))
;; <-------------->
;; 1 -- 2
(check-equal? (ivl-join (ivl #f #f) (ivl 1 2)) (ivl 1 2))
;; 1 -------->
;; <-------- 2
(check-equal? (ivl-join (ivl 1 #f) (ivl #f 2)) (ivl 1 2))
;; <-------- 2
;; <------------- 3
(check-equal? (ivl-join (ivl #f 2) (ivl #f 3)) (ivl #f 3))
;; 0 ------------->
;; 1 -------->
(check-equal? (ivl-join (ivl 0 #f) (ivl 1 #f)) (ivl 0 #f))
;; Three not specified
;; <-------------->
;; 1 -------->
(check-equal? (ivl-join (ivl #f #f) (ivl 1 #f)) (ivl 1 #f))
;; <-------------->
;; <-------- 2
(check-equal? (ivl-join (ivl #f #f) (ivl #f 2)) (ivl #f 2))
;; Four not specified
(check-equal? (ivl-join (ivl #f #f) (ivl #f #f)) (ivl #f #f))
;; One infinite
;; <--- 1 2 -- 3
(check-equal? (ivl-join (ivl -inf.0 1) (ivl 2 3)) (ivl -inf.0 3))
;; 0 -- 1 2 --->
(check-equal? (ivl-join (ivl 0 1) (ivl 2 +inf.0)) (ivl 0 +inf.0))
;; <-------- 2
;; 1 ------- 3
(check-equal? (ivl-join (ivl -inf.0 2) (ivl 1 3)) (ivl -inf.0 3))
;; 2 --->
;; 0 ------------ 3
(check-equal? (ivl-join (ivl 2 +inf.0) (ivl 0 3)) (ivl 0 +inf.0))
;; <------------- 3
;; 1 -- 2
(check-equal? (ivl-join (ivl -inf.0 3) (ivl 1 2)) (ivl -inf.0 3))
;; 0 ------------->
;; 1 -- 2
(check-equal? (ivl-join (ivl 0 +inf.0) (ivl 1 2)) (ivl 0 +inf.0))
;; Two infinite
;; <-------------->
;; 1 -- 2
(check-equal? (ivl-join (ivl -inf.0 +inf.0) (ivl 1 2)) (ivl -inf.0 +inf.0))
;; 1 -------->
;; <-------- 2
(check-equal? (ivl-join (ivl 1 +inf.0) (ivl -inf.0 2)) (ivl -inf.0 +inf.0))
;; <--- 1 2 --->
(check-equal? (ivl-join (ivl -inf.0 1) (ivl 2 +inf.0)) (ivl -inf.0 +inf.0))
;; <-------- 2
;; <------------- 3
(check-equal? (ivl-join (ivl -inf.0 2) (ivl -inf.0 3)) (ivl -inf.0 3))
;; 0 ------------->
;; 1 -------->
(check-equal? (ivl-join (ivl 0 +inf.0) (ivl 1 +inf.0)) (ivl 0 +inf.0))
;; Three infinite
;; <-------------->
;; 1 -------->
(check-equal? (ivl-join (ivl -inf.0 +inf.0) (ivl 1 +inf.0)) (ivl -inf.0 +inf.0))
;; <-------------->
;; <-------- 2
(check-equal? (ivl-join (ivl -inf.0 +inf.0) (ivl -inf.0 2)) (ivl -inf.0 +inf.0))
;; Four infinite
(check-equal? (ivl-join (ivl -inf.0 +inf.0) (ivl -inf.0 +inf.0)) (ivl -inf.0 +inf.0))
;; ===================================================================================================
;; Vectors
(check-true (vector-andmap zero? #(0 0 0 0)))
(check-false (vector-andmap zero? #(0 0 1 0)))
(check-true (vector-andmap (λ (x y) (and (= x 1) (= y 2)))
#(1 1 1 1)
#(2 2 2 2)))
(check-false (vector-andmap (λ (x y) (and (= x 1) (= y 2)))
#(1 1 1 1)
#(2 1 2 2)))
(check-true (vector-ormap zero? #(0 0 1 0)))
(check-false (vector-ormap zero? #(1 1 1 1)))
(check-true (vector-ormap (λ (x y) (and (= x 1) (= y 2)))
#(0 0 1 0)
#(0 0 2 0)))
(check-false (vector-ormap (λ (x y) (and (= x 1) (= y 2)))
#(0 0 1 0)
#(0 2 0 0)))
;; ===================================================================================================
;; Worker threads
(let ()
(define wt (make-worker-thread (match-lambda
[(list x y z) (sleep 0.1)
(+ x y z)])))
(collect-garbage)
(collect-garbage)
(check-true (worker-thread-waiting? wt))
(check-true (worker-thread-put wt (list 1 2 3)))
(check-true (worker-thread-working? wt))
(check-equal? (worker-thread-get wt) 6)
(check-true (worker-thread-put wt (list 1 2 3)))
(check-false (worker-thread-try-put wt (list 10 20 30)))
(check-exn exn? (λ () (worker-thread-put wt (list 10 20 30))))
(check-false (worker-thread-try-get wt))
(sleep 0.2)
(check-equal? (worker-thread-try-get wt) 6)
(check-true (worker-thread-put wt (list 10 20 30)))
(check-equal? (worker-thread-send wt (list 1 2 3)) 6)
(check-exn exn? (λ () (worker-thread-get wt)))
(check-false (worker-thread-try-get wt))
(check-true (worker-thread-try-put wt (list 1 2 3)))
(sleep 0.2)
(check-false (worker-thread-try-put wt (list 10 20 30)))
(check-equal? (worker-thread-wait wt) (void))
(check-true (worker-thread-put wt (list 1 2)))
(check-exn exn? (λ () (worker-thread-get wt)))
)