func TestRunIncomes(t *testing.T) { JsonObj := []byte(`{"Age":22, "Retirement_age":65, "Terminal_age":90, "Effective_tax_rate":0.3, "Returns_tax_rate":0.3, "N": 20000, "Non_Taxable_contribution":17500, "Taxable_contribution": 0, "Non_Taxable_balance":0, "Taxable_balance": 0, "Yearly_social_security_income":0, "Asset_volatility": 0.15, "Expected_rate_of_return": 0.07, "Inflation_rate":0.035}`) rc, err := NewRetCalcFromJSON(JsonObj) if err != nil { t.Error(err) } runIncomes := rc.RunIncomes() sort.Float64s(runIncomes) incomePerRun := make([]float64, rc.N, rc.N) for i := range incomePerRun { incomePerRun[i] = rc.IncomeOnPath(i) } sort.Float64s(incomePerRun) incomesOk := true for i := range incomePerRun { if incomePerRun[i] != runIncomes[i] { incomesOk = false fmt.Printf("RunIncomes: %f, IncomeOnPath: %f\n", runIncomes[i], incomePerRun[i]) } } if !incomesOk { t.Errorf("Incomes do not calculate correctly for RunIncomes()") } if !sort.Float64sAreSorted(runIncomes) { t.Errorf("Incomes from RetCalc.RunIncomes() should be sorted on return") } }
func (res *Results) med() { slice := res.copyTook() if !sort.Float64sAreSorted(slice) { sort.Float64s(slice) } l := len(slice) switch l { case 0: res.TookMed = float64(0) case 1: res.TookMed = slice[0] case 2: res.TookMed = slice[1] default: if math.Mod(float64(l), 2) == 0 { index := int(math.Floor(float64(l)/2) - 1) lower := slice[index] upper := slice[index+1] res.TookMed = (lower + upper) / 2 } else { res.TookMed = slice[l/2] } } }
func TestFloat64s(t *testing.T) { data := float64s Sort(sort.Float64Slice(data[0:])) if !sort.Float64sAreSorted(data[0:]) { t.Errorf("sorted %v", float64s) t.Errorf(" got %v", data) } }
func (res *Results) min() { slice := res.copyTook() if !sort.Float64sAreSorted(slice) { sort.Float64s(slice) } res.TookMin = slice[0] }
func (res *Results) max() { slice := res.copyTook() if !sort.Float64sAreSorted(slice) { sort.Float64s(slice) } res.TookMax = slice[len(slice)-1] }
// sortedCopyDif returns a sorted copy of float64s // only if the original data isn't sorted. // Only use this if returned slice won't be manipulated! func sortedCopyDif(input Float64Data) (copy Float64Data) { if sort.Float64sAreSorted(input) { return input } copy = copyslice(input) sort.Float64s(copy) return }
func (sf64 *SliceFloat64) Max() (float64, error) { if len(sf64.Elements) == 0 { return 0, errors.New("List is empty") } if !sort.Float64sAreSorted(sf64.Elements) { sort.Float64s(sf64.Elements) } return sf64.Elements[len(sf64.Elements)-1], nil }
func TestSort(t *testing.T) { r := testData() SortBYOB(r, make([]float64, len(r))) if !sort.Float64sAreSorted(r) { log.Printf("Should have sorted slice.\n") log.Printf("Data was %v", r) t.FailNow() } }
func (sf64 *SliceFloat64) Median() (float64, error) { if len(sf64.Elements) == 0 { return 0, errors.New("List is empty") } if !sort.Float64sAreSorted(sf64.Elements) { sort.Float64s(sf64.Elements) } mid := int64(float64(len(sf64.Elements)) / 2) return sf64.Elements[mid], nil }
func TestSortRand(t *testing.T) { test := func(r []float64) bool { SortBYOB(r, make([]float64, len(r))) return sort.Float64sAreSorted(r) } if err := quick.Check(test, nil); err != nil { t.Error(err) } }
// extractXY should return one series with its x values sorted. func TestExtractXY(t *testing.T) { vals, _ := seriesTestDefaultData(5) series := extractXY(vals, "X", "Y") if len(series) != 1 { t.Fatalf("extractXY returned > 1 series") } s := series[0] if !sort.Float64sAreSorted(s.xs) { t.Fatalf("extractXY returned incorrectly sorted series") } }
// Sort sorts the samples in place in s and returns s. // // A sorted sample improves the performance of some algorithms. func (s *Sample) Sort() *Sample { if s.Sorted || sort.Float64sAreSorted(s.Xs) { // All set } else if s.Weights == nil { sort.Float64s(s.Xs) } else { sort.Sort(&sampleSorter{s.Xs, s.Weights}) } s.Sorted = true return s }
func TestFloat64s(t *testing.T) { data := float64s for _, alg := range algorithms { sorting.Float64s(data[:], alg) if !sort.Float64sAreSorted(data[:]) { t.Errorf("%v\n", util.GetFuncName(alg)) t.Errorf("sorted: %v\n", float64s) t.Errorf(" got: %v\n", data) } } }
func TestAdjustLeftRight(t *testing.T) { keys := []float64{1, 2, 3, 4, 9, 5, 6, 7, 8} counts := []uint32{1, 2, 3, 4, 9, 5, 6, 7, 8} s := summary{keys: keys, counts: counts} s.adjustRight(4) if !sort.Float64sAreSorted(s.keys) || s.counts[4] != 5 { t.Errorf("adjustRight should have fixed the keys/counts state. %v %v", s.keys, s.counts) } keys = []float64{1, 2, 3, 4, 0, 5, 6, 7, 8} counts = []uint32{1, 2, 3, 4, 0, 5, 6, 7, 8} s = summary{keys: keys, counts: counts} s.adjustLeft(4) if !sort.Float64sAreSorted(s.keys) || s.counts[4] != 4 { t.Errorf("adjustLeft should have fixed the keys/counts state. %v %v", s.keys, s.counts) } }
func Median(list []float64) (float64, error) { if len(list) == 0 { return 0.0, errors.New("Empty list given") } if !sort.Float64sAreSorted(list) { sort.Float64s(list) } if len(list)%2 == 1 { return list[(len(list) / 2)], nil } return (list[len(list)/2] + list[len(list)/2-1]) / 2, nil }
func TestSortCopy(t *testing.T) { x := testData() y := SortCopy(x) if !sort.Float64sAreSorted(y) { log.Printf("Should have sorted slice.\n") log.Printf("Data was %v", y) t.FailNow() } if x[0] != 3.1415 || x[10] != math.SmallestNonzeroFloat64 { log.Printf("Slice should have not have been modified.\n") log.Printf("Data was %v", y) t.FailNow() } }
// Integrate a function from a to b using cubic spline interpolation to // approximate the function specified at the points xs with values ys. // xs must be sorted and of the same length as ys, and (a, b) must be // within (xs[0], xs[len(xs)-1]). func Spline(xs, ys []float64, a, b float64) (float64, error) { // check preconditions N := len(xs) if N != len(ys) { return 0.0, fmt.Errorf("xs and ys must have the same length for spline interpolation") } if !sort.Float64sAreSorted(xs) { return 0.0, fmt.Errorf("xs values must be sorted for spline interpolation") } if a < xs[0] || b > xs[len(xs)-1] { return 0.0, fmt.Errorf("Spline integration bounds must be within xs") } // do spline integration val := C.integrate_spline(unsafe.Pointer(&xs), unsafe.Pointer(&ys), C.int(N), C.double(a), C.double(b)) return float64(val), nil }
//Sorts b by ascending x value func (b *BiVariateData) Sort() { //edge case 1 if b.isSorted { return } //edge case 2 if sort.Float64sAreSorted(b.Xs) { b.isSorted = true return } sort.Sort(b) b.isSorted = true }
// Trapezoidal estimates the integral of a function f // \int_a^b f(x) dx // from a set of evaluations of the function using the trapezoidal rule. // The trapezoidal rule makes piecewise linear approximations to the function, // and estimates // \int_x[i]^x[i+1] f(x) dx // as // (x[i+1] - x[i]) * (f[i] + f[i+1])/2 // where f[i] is the value of the function at x[i]. // More details on the trapezoidal rule can be found at: // https://en.wikipedia.org/wiki/Trapezoidal_rule // // The (x,f) input data points must be sorted along x. // One can use github.com/gonum/stat.SortWeighted to do that. // The x and f slices must be of equal length and have length > 1. func Trapezoidal(x, f []float64) float64 { switch { case len(x) != len(f): panic("integrate: slice length mismatch") case len(x) < 2: panic("integrate: input data too small") case !sort.Float64sAreSorted(x): panic("integrate: input must be sorted") } integral := 0.0 for i := 0; i < len(x)-1; i++ { integral += 0.5 * (x[i+1] - x[i]) * (f[i+1] + f[i]) } return integral }
// Within returns the first index i where s[i] <= v < s[i+1]. Within panics if: // - len(s) < 2 // - s is not sorted func Within(s []float64, v float64) int { if len(s) < 2 { panic("floats: slice length less than 2") } if !sort.Float64sAreSorted(s) { panic("floats: input slice not sorted") } if v < s[0] || v >= s[len(s)-1] || math.IsNaN(v) { return -1 } for i, f := range s[1:] { if v < f { return i } } return -1 }
// ExtractSeries should return a []Series with length equal to the number of // values of z passed in to it. Individual series should have their x values // sorted. func TestExtractSeries(t *testing.T) { vals, errs := seriesTestDefaultData(6) series, zVals := ExtractSeries(vals, errs, []string{"X", "Y", "Z"}, nil, nil, nil, false) if zVals[0] != 0.0 || zVals[1] != 1.0 { t.Fatalf("ExtractSeries returned incorrect z values") } expectedLength := 2 if len(series) != expectedLength { t.Fatalf("ExtractSeries returned incorrect number of series") } for i := 0; i < expectedLength; i++ { s := series[i] if !sort.Float64sAreSorted(s.xs) { t.Fatalf("ExtractSeries returned incorrectly sorted series") } } }
// Median returns the median value of the data. func Median(x []float64) float64 { if len(x) == 0 { return 0 } if sort.Float64sAreSorted(x) { return x[len(x)/2] } h := new(floats) heap.Init(h) for _, f := range x { heap.Push(h, f) } for i := 0; i < len(x)/2; i++ { heap.Pop(h) } return heap.Pop(h).(float64) }
func Median(arr []float64) float64 { n := len(arr) var thisarr []float64 if !sort.Float64sAreSorted(arr) { thisarr = make([]float64, n) copy(arr, thisarr) sort.Float64s(thisarr) } else { thisarr = arr } if n%2 == 0 { j := n / 2 return (thisarr[j] + thisarr[j+1]) / 2 } else { return thisarr[(n+1)/2] } }
// CDF returns the empirical cumulative distribution function value of x, that is // the fraction of the samples less than or equal to q. The // exact behavior is determined by the CumulantKind. CDF is theoretically // the inverse of the Quantile function, though it may not be the actual inverse // for all values q and CumulantKinds. // // The x data must be sorted in increasing order. If weights is nil then all // of the weights are 1. If weights is not nil, then len(x) must equal len(weights). // // CumulantKind behaviors: // - Empirical: Returns the lowest fraction for which q is greater than or equal // to that fraction of samples func CDF(q float64, c CumulantKind, x, weights []float64) float64 { if weights != nil && len(x) != len(weights) { panic("stat: slice length mismatch") } if floats.HasNaN(x) { return math.NaN() } if !sort.Float64sAreSorted(x) { panic("x data are not sorted") } if q < x[0] { return 0 } if q >= x[len(x)-1] { return 1 } var sumWeights float64 if weights == nil { sumWeights = float64(len(x)) } else { sumWeights = floats.Sum(weights) } // Calculate the index switch c { case Empirical: // Find the smallest value that is greater than that percent of the samples var w float64 for i, v := range x { if v > q { return w / sumWeights } if weights == nil { w++ } else { w += weights[i] } } panic("impossible") default: panic("stat: bad cumulant kind") } }
func MedianFloat64(data []float64) float64 { if sort.Float64sAreSorted(data) { if len(data)%2 == 1 { return data[len(data)/2] } else { return (data[len(data)/2] + data[len(data)/2-1]) / 2.0 } } else { sort.Float64s(data) if len(data)%2 == 1 { return data[len(data)/2] } else { return (data[len(data)/2] + data[len(data)/2-1]) / 2.0 } } panic("Error in MedianInt") return -1 }
// Fit sets the parameters of the probability distribution from the // data samples x with relative weights w. // If weights is nil, then all the weights are 1. // If weights is not nil, then the len(weights) must equal len(samples). // // Note: Laplace distribution has no FitPrior because it has no sufficient // statistics. func (l *Laplace) Fit(samples, weights []float64) { if len(samples) != len(weights) { panic(badLength) } if len(samples) == 0 { panic(badNoSamples) } if len(samples) == 1 { l.Mu = samples[0] l.Scale = 0 return } var ( sortedSamples []float64 sortedWeights []float64 ) if sort.Float64sAreSorted(samples) { sortedSamples = samples sortedWeights = weights } else { // Need to copy variables so the input variables aren't effected by the sorting sortedSamples = make([]float64, len(samples)) copy(sortedSamples, samples) sortedWeights := make([]float64, len(samples)) copy(sortedWeights, weights) stat.SortWeighted(sortedSamples, sortedWeights) } // The (weighted) median of the samples is the maximum likelihood estimate // of the mean parameter // TODO: Rethink quantile type when stat has more options l.Mu = stat.Quantile(0.5, stat.Empirical, sortedSamples, sortedWeights) sumWeights := floats.Sum(weights) // The scale parameter is the average absolute distance // between the sample and the mean absError := stat.MomentAbout(1, samples, l.Mu, weights) l.Scale = absError / sumWeights }
func TestNormalizeExpenses(t *testing.T) { var list []float64 = []float64{4.0, 1.0, 2.0, 3.0, 2.00, 2.0, 5.0} normalized := normalizeExpenses(list) if !sort.Float64sAreSorted(normalized) { t.Fatalf("Expected normalized list to be sorted.") } var count float64 = 0 for _, x := range normalized { if x == 2.0 { count++ } } if count > 1 { t.Fatalf("Expected one instance of 2.0. Actual: %v", count) } }
func main() { // スライス is := make([]int, 0, 4) // len(is) = 0, cap(is) = 4 fmt.Println("len(is)=", len(is), ", cap(is)=", cap(is)) for i := 0; i < 10; i++ { is = append(is, 10-i-1) } fmt.Println("len(is)=", len(is), ", cap(is)=", cap(is)) for i, x := range is { fmt.Println(i, ":", x) } sort.Ints(is) for i, x := range is { fmt.Println(i, ":", x) } fmt.Println(sort.IntsAreSorted(is)) fs := make([]float64, 0, 4) for i := 0.0; i < 1.0; i += 0.1 { fs = append(fs, 1.0-i-0.1) } for i, x := range fs { fmt.Println(i, ":", x) } sort.Float64s(fs) for i, x := range fs { fmt.Println(i, ":", x) } fmt.Println(sort.Float64sAreSorted(fs)) // 連想配列 m := make(map[int]string, 3) m[1] = "hoge" m[2] = "fuga" m[3] = "bar" fmt.Println(m) delete(m, 2) for k, v := range m { fmt.Println(k, ":", v) } }
// Quantile returns the sample of x such that x is greater than or // equal to the fraction p of samples. The exact behavior is determined by the // CumulantKind, and p should be a number between 0 and 1. Quantile is theoretically // the inverse of the CDF function, though it may not be the actual inverse // for all values p and CumulantKinds. // // The x data must be sorted in increasing order. If weights is nil then all // of the weights are 1. If weights is not nil, then len(x) must equal len(weights). // // CumulantKind behaviors: // - Empirical: Returns the lowest value q for which q is greater than or equal // to the fraction p of samples func Quantile(p float64, c CumulantKind, x, weights []float64) float64 { if !(p >= 0 && p <= 1) { panic("stat: percentile out of bounds") } if weights != nil && len(x) != len(weights) { panic("stat: slice length mismatch") } if floats.HasNaN(x) { return math.NaN() // This is needed because the algorithm breaks otherwise } if !sort.Float64sAreSorted(x) { panic("x data are not sorted") } var sumWeights float64 if weights == nil { sumWeights = float64(len(x)) } else { sumWeights = floats.Sum(weights) } switch c { case Empirical: var cumsum float64 fidx := p * sumWeights for i := range x { if weights == nil { cumsum++ } else { cumsum += weights[i] } if cumsum >= fidx { return x[i] } } panic("impossible") default: panic("stat: bad cumulant kind") } }
// Helper method for (*Results).calculatePercentiles which actually // finds the percentile from the passed slice of connection times. func percentile(times []float64, pct int) float64 { length := len(times) if length == 1 { return times[0] } if length == 2 { return times[1] } var times64 []float64 for _, float := range times { times64 = append(times64, float64(float)) } if !sort.Float64sAreSorted(times64) { sort.Float64s(times64) } index := int(math.Floor(((float64(length)/100)*float64(pct))+0.5)) - 1 return float64(times64[index]) }