Skip to content

Commit

Permalink
quantiler interface
Browse files Browse the repository at this point in the history
  • Loading branch information
cshenton committed Feb 24, 2018
1 parent e20249c commit 270df8a
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 10 deletions.
7 changes: 7 additions & 0 deletions dist/uv/interfaces.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package uv

// Quantiler defines distributions that have computable quantiles. That is,
// which accept a probability on [0,1] and return a member in their support.
type Quantiler interface {
Quantile(p float64) (q float64, err error)
}
9 changes: 7 additions & 2 deletions dist/uv/lognormal.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ func NewLogNormal(location, scale float64) (ln *LogNormal, err error) {
}

// Quantile is the inverse function of the log normal CDF.
func (ln *LogNormal) Quantile(p float64) float64 {
return math.Exp(ln.Location + ln.Scale*mathext.NormalQuantile(p))
func (ln *LogNormal) Quantile(p float64) (q float64, err error) {
if p < 0 || p > 1 {
err := errors.New("probabilities must be between 0 and 1")
return q, err
}
q = math.Exp(ln.Location + ln.Scale*mathext.NormalQuantile(p))
return q, nil
}
24 changes: 21 additions & 3 deletions dist/uv/lognormal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,27 @@ func TestLogNormalQuantile(t *testing.T) {

ln, err := uv.NewLogNormal(loc, scale)
if err != nil {
t.Error("unexpected error in NewNormal,", err)
t.Error("unexpected error in NewLogNormal,", err)
}
if math.Abs(ln.Quantile(0.5)-math.Exp(loc)) > 1e-8 {
t.Errorf("expected median quantile %v, but got %v", math.Exp(loc), ln.Quantile(0.5))
q, err := ln.Quantile(0.5)
if err != nil {
t.Error("unexpected error in Quantile,", err)
}
if math.Abs(q-math.Exp(loc)) > 1e-8 {
t.Errorf("expected median quantile %v, but got %v", math.Exp(loc), q)
}
}

func TestLogNormalQuantileErrs(t *testing.T) {
loc := 0.0
scale := 1.0

ln, err := uv.NewLogNormal(loc, scale)
if err != nil {
t.Error("unexpected error in NewLogNormal,", err)
}
_, err = ln.Quantile(2)
if err == nil {
t.Error("expected error, but it was nil")
}
}
9 changes: 7 additions & 2 deletions dist/uv/normal.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ func (n *Normal) Variance() float64 {
}

// Quantile is the inverse function of the CDF.
func (n *Normal) Quantile(p float64) float64 {
return n.Location + n.Scale*mathext.NormalQuantile(p)
func (n *Normal) Quantile(p float64) (q float64, err error) {
if p < 0 || p > 1 {
err := errors.New("probabilities must be between 0 and 1")
return q, err
}
q = n.Location + n.Scale*mathext.NormalQuantile(p)
return q, nil
}
23 changes: 20 additions & 3 deletions dist/uv/normal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ func TestNewNormal(t *testing.T) {
if n.Scale != tc.scale {
t.Errorf("expected Scale %v, but got %v", tc.scale, n.Scale)
}

})
}
}
Expand Down Expand Up @@ -88,7 +87,25 @@ func TestNormalQuantile(t *testing.T) {
if err != nil {
t.Error("unexpected error in NewNormal,", err)
}
if math.Abs(n.Quantile(0.5)-loc) > 1e-8 {
t.Errorf("expected median quantile %v, but got %v", loc, n.Quantile(0.5))
q, err := n.Quantile(0.5)
if err != nil {
t.Error("unexpected error in Quantile,", err)
}
if math.Abs(q-loc) > 1e-8 {
t.Errorf("expected median quantile %v, but got %v", loc, q)
}
}

func TestNormalQuantileErrs(t *testing.T) {
loc := 0.0
scale := 1.0

n, err := uv.NewNormal(loc, scale)
if err != nil {
t.Error("unexpected error in NewNormal,", err)
}
_, err = n.Quantile(2)
if err == nil {
t.Error("expected error, but it was nil")
}
}

0 comments on commit 270df8a

Please sign in to comment.