189 lines
5.5 KiB
Go
189 lines
5.5 KiB
Go
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package scale
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"math"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/aclements/go-moremath/internal/mathtest"
|
||
|
"github.com/aclements/go-moremath/vec"
|
||
|
)
|
||
|
|
||
|
func TestLog(t *testing.T) {
|
||
|
l, err := NewLog(0, 10, 10)
|
||
|
if _, ok := err.(RangeErr); !ok {
|
||
|
t.Errorf("want RangeErr; got %v", err)
|
||
|
}
|
||
|
l, err = NewLog(-10, 0, 10)
|
||
|
if _, ok := err.(RangeErr); !ok {
|
||
|
t.Errorf("want RangeErr; got %v", err)
|
||
|
}
|
||
|
l, err = NewLog(-10, 10, 10)
|
||
|
if _, ok := err.(RangeErr); !ok {
|
||
|
t.Errorf("want RangeErr; got %v", err)
|
||
|
}
|
||
|
l, err = NewLog(10, 20, 0)
|
||
|
if _, ok := err.(RangeErr); !ok {
|
||
|
t.Errorf("want RangeErr; got %v", err)
|
||
|
}
|
||
|
|
||
|
l, _ = NewLog(1, 10, 10)
|
||
|
mathtest.WantFunc(t, fmt.Sprintf("%v.Map", l), l.Map,
|
||
|
map[float64]float64{
|
||
|
-1: math.NaN(),
|
||
|
0: math.NaN(),
|
||
|
0.1: -1,
|
||
|
1: 0,
|
||
|
math.Pow(10, 0.5): 0.5,
|
||
|
10: 1,
|
||
|
100: 2,
|
||
|
})
|
||
|
mathtest.WantFunc(t, fmt.Sprintf("%v.Unmap", l), l.Unmap,
|
||
|
map[float64]float64{
|
||
|
-1: 0.1,
|
||
|
0: 1,
|
||
|
0.5: math.Pow(10, 0.5),
|
||
|
1: 10,
|
||
|
2: 100,
|
||
|
})
|
||
|
|
||
|
l.SetClamp(true)
|
||
|
mathtest.WantFunc(t, fmt.Sprintf("%v.Map", l), l.Map,
|
||
|
map[float64]float64{
|
||
|
-1: math.NaN(),
|
||
|
0: math.NaN(),
|
||
|
0.1: 0,
|
||
|
1: 0,
|
||
|
math.Pow(10, 0.5): 0.5,
|
||
|
10: 1,
|
||
|
100: 1,
|
||
|
})
|
||
|
mathtest.WantFunc(t, fmt.Sprintf("%v.Unmap", l), l.Unmap,
|
||
|
map[float64]float64{
|
||
|
0: 1,
|
||
|
0.5: math.Pow(10, 0.5),
|
||
|
1: 10,
|
||
|
})
|
||
|
|
||
|
l, _ = NewLog(-1, -10, 10)
|
||
|
mathtest.WantFunc(t, fmt.Sprintf("%v.Map", l), l.Map,
|
||
|
map[float64]float64{
|
||
|
1: math.NaN(),
|
||
|
0: math.NaN(),
|
||
|
-0.1: 2,
|
||
|
-1: 1,
|
||
|
-math.Pow(10, 0.5): 0.5,
|
||
|
-10: 0,
|
||
|
-100: -1,
|
||
|
})
|
||
|
mathtest.WantFunc(t, fmt.Sprintf("%v.Unmap", l), l.Unmap,
|
||
|
map[float64]float64{
|
||
|
2: -0.1,
|
||
|
1: -1,
|
||
|
0.5: -math.Pow(10, 0.5),
|
||
|
0: -10,
|
||
|
-1: -100,
|
||
|
})
|
||
|
|
||
|
l, _ = NewLog(5, 5, 10)
|
||
|
mathtest.WantFunc(t, fmt.Sprintf("%v.Map", l), l.Map,
|
||
|
map[float64]float64{
|
||
|
-1: math.NaN(),
|
||
|
0: math.NaN(),
|
||
|
1: 0.5,
|
||
|
10: 0.5,
|
||
|
})
|
||
|
mathtest.WantFunc(t, fmt.Sprintf("%v.Unmap", l), l.Unmap,
|
||
|
map[float64]float64{
|
||
|
0: 5,
|
||
|
0.5: 5,
|
||
|
1: 5,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestLogTicks(t *testing.T) {
|
||
|
m := func(m int) TickOptions {
|
||
|
return TickOptions{Max: m}
|
||
|
}
|
||
|
|
||
|
// Test the obvious.
|
||
|
l, _ := NewLog(1, 10, 10)
|
||
|
major, minor := l.Ticks(m(5))
|
||
|
wmajor, wminor := vec.Logspace(0, 1, 2, 10), vec.Linspace(1, 10, 10)
|
||
|
if !ticksEq(major, wmajor, minor, wminor) {
|
||
|
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
|
||
|
}
|
||
|
|
||
|
// Test two orders of magnitude.
|
||
|
l, _ = NewLog(1, 100, 10)
|
||
|
major, minor = l.Ticks(m(5))
|
||
|
wmajor, wminor = vec.Logspace(0, 2, 3, 10), vec.Concat(vec.Linspace(1, 9, 9), vec.Linspace(10, 100, 10))
|
||
|
if !ticksEq(major, wmajor, minor, wminor) {
|
||
|
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
|
||
|
}
|
||
|
|
||
|
// Test many orders of magnitude (higher tick levels).
|
||
|
l, _ = NewLog(1, 1e8, 10)
|
||
|
major, minor = l.Ticks(m(5))
|
||
|
wmajor, wminor = vec.Logspace(0, 4, 5, 100), vec.Logspace(0, 8, 9, 10)
|
||
|
if !ticksEq(major, wmajor, minor, wminor) {
|
||
|
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
|
||
|
}
|
||
|
|
||
|
major, minor = l.Ticks(m(4))
|
||
|
wmajor, wminor = vec.Logspace(0, 2, 3, 10000), vec.Logspace(0, 4, 5, 100)
|
||
|
if !ticksEq(major, wmajor, minor, wminor) {
|
||
|
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
|
||
|
}
|
||
|
|
||
|
// Test minor ticks outside major ticks.
|
||
|
l, _ = NewLog(0.91, 200, 10)
|
||
|
major, minor = l.Ticks(m(5))
|
||
|
wmajor, wminor = vec.Logspace(0, 2, 3, 10), vec.Concat(vec.Linspace(1, 9, 9), vec.Linspace(10, 100, 10), []float64{200})
|
||
|
if !ticksEq(major, wmajor, minor, wminor) {
|
||
|
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
|
||
|
}
|
||
|
|
||
|
// Test nicing.
|
||
|
l.Nice(m(5))
|
||
|
major, minor = l.Ticks(m(5))
|
||
|
wmajor, wminor = vec.Logspace(-1, 3, 5, 10), vec.Concat(vec.Linspace(0.1, 0.9, 9), vec.Linspace(1, 9, 9), vec.Linspace(10, 90, 9), vec.Linspace(100, 1000, 10))
|
||
|
if !ticksEq(major, wmajor, minor, wminor) {
|
||
|
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
|
||
|
}
|
||
|
|
||
|
// Test negative ticks.
|
||
|
neg := vec.Vectorize(func(x float64) float64 { return -x })
|
||
|
l, _ = NewLog(-1, -100, 10)
|
||
|
major, minor = l.Ticks(m(5))
|
||
|
wmajor, wminor = neg(vec.Logspace(2, 0, 3, 10)), neg(vec.Concat(vec.Linspace(100, 10, 10), vec.Linspace(9, 1, 9)))
|
||
|
if !ticksEq(major, wmajor, minor, wminor) {
|
||
|
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
|
||
|
}
|
||
|
|
||
|
major, minor = l.Ticks(m(2))
|
||
|
wmajor, wminor = neg(vec.Logspace(1, 0, 2, 100)), neg(vec.Logspace(2, 0, 3, 10))
|
||
|
if !ticksEq(major, wmajor, minor, wminor) {
|
||
|
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
|
||
|
}
|
||
|
|
||
|
l.Nice(m(5))
|
||
|
major, minor = l.Ticks(m(5))
|
||
|
wmajor, wminor = neg(vec.Logspace(2, 0, 3, 10)), neg(vec.Concat(vec.Linspace(100, 10, 10), vec.Linspace(9, 1, 9)))
|
||
|
if !ticksEq(major, wmajor, minor, wminor) {
|
||
|
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
|
||
|
}
|
||
|
|
||
|
// Test Min==Max.
|
||
|
l, _ = NewLog(5, 5, 10)
|
||
|
major, minor = l.Ticks(m(5))
|
||
|
wmajor, wminor = []float64{5}, []float64{5}
|
||
|
if !ticksEq(major, wmajor, minor, wminor) {
|
||
|
t.Errorf("%v.Ticks(5) = %v, %v; want %v, %v", l, major, minor, wmajor, wminor)
|
||
|
}
|
||
|
}
|