// run_rootsol_test runs root solution test // Note: xguess is the trial solution for Newton's method (not Brent's) func run_rootsol_test(tst *testing.T, xa, xb, xguess, tolcmp float64, ffcnA Cb_yxe, ffcnB Cb_f, JfcnB Cb_Jd, fname string, save, show bool) (xbrent float64) { // Brent io.Pfcyan("\n - - - - - - - using Brent's method - - -- - - - \n") var o Brent o.Init(ffcnA) var err error xbrent, err = o.Solve(xa, xb, false) if err != nil { chk.Panic("%v", err) } var ybrent float64 ybrent, err = ffcnA(xbrent) if err != nil { chk.Panic("%v", err) } io.Pforan("x = %v\n", xbrent) io.Pforan("f(x) = %v\n", ybrent) io.Pforan("nfeval = %v\n", o.NFeval) io.Pforan("nit = %v\n", o.It) if math.Abs(ybrent) > 1e-10 { chk.Panic("Brent failed: f(x) = %g > 1e-10\n", ybrent) } // Newton io.Pfcyan("\n - - - - - - - using Newton's method - - -- - - - \n") var p NlSolver p.Init(1, ffcnB, nil, JfcnB, true, false, nil) xnewt := []float64{xguess} var cnd float64 cnd, err = p.CheckJ(xnewt, 1e-6, true, !chk.Verbose) io.Pforan("cond(J) = %v\n", cnd) if err != nil { chk.Panic("%v", err.Error()) } err = p.Solve(xnewt, false) if err != nil { chk.Panic("%v", err.Error()) } var ynewt float64 ynewt, err = ffcnA(xnewt[0]) if err != nil { chk.Panic("%v", err) } io.Pforan("x = %v\n", xnewt[0]) io.Pforan("f(x) = %v\n", ynewt) io.Pforan("nfeval = %v\n", p.NFeval) io.Pforan("nJeval = %v\n", p.NJeval) io.Pforan("nit = %v\n", p.It) if math.Abs(ynewt) > 1e-9 { chk.Panic("Newton failed: f(x) = %g > 1e-10\n", ynewt) } // compare Brent's and Newton's solutions PlotYxe(ffcnA, "results", fname, xbrent, xa, xb, 101, "Brent", "'b-'", save, show, func() { plt.PlotOne(xnewt[0], ynewt, "'g+', ms=15, label='Newton'") }) chk.Scalar(tst, "xbrent - xnewt", tolcmp, xbrent, xnewt[0]) return }
func (sp *SmoothFollow) LateUpdate() { camera := engine.CurrentCamera() if camera != nil { myPos := sp.Target.Transform().Position() camPos := camera.Transform().Position() if sp.Speed > 0 { camPos = engine.Lerp(camPos, myPos, float32(engine.DeltaTime())*sp.Speed) disX := camPos.X - myPos.X disY := camPos.Y - myPos.Y if float32(math.Abs(float64(disX))) > sp.MaxDis { if disX < 0 { camPos.X = myPos.X - sp.MaxDis } else { camPos.X = myPos.X + sp.MaxDis } } if float32(math.Abs(float64(disY))) > sp.MaxDis { if disY < 0 { camPos.Y = myPos.Y - sp.MaxDis } else { camPos.Y = myPos.Y + sp.MaxDis } } } else { camPos = myPos } camera.Transform().SetPosition(camPos) } }
func nearEqual(a, b, closeEnough, maxError float64) bool { absDiff := math.Abs(a - b) if absDiff < closeEnough { // Necessary when one value is zero and one value is close to zero. return true } return absDiff/max(math.Abs(a), math.Abs(b)) < maxError }
func bestScaleAndPrefix(unit *pb.TelemetryDatumSchema_Unit, values ...float64) (scale float64, prefix string) { // Heuristic (can be improved): // Use the smallest value. m := math.Abs(values[0]) for _, v := range values { v = math.Abs(v) if v > m { m = v } } prefixes := []struct { string float64 }{ {"T", 1e12}, {"G", 1e9}, {"M", 1e6}, {"k", 1e3}, {"", 1e0}, {"m", 1e-3}, {"μ", 1e-6}, {"n", 1e-9}, {"p", 1e-12}} for _, s := range prefixes { if m >= s.float64 { return s.float64, s.string } } return 1.0, "" }
// PlotRamp plots the ramp function (contour) func (o *Plotter) DrawRamp(xmi, xma, ymi, yma float64) { if o.Rmpf == nil { o.set_empty() return } if o.NptsRmp < 2 { o.NptsRmp = 101 } if math.Abs(xma-xmi) < 1e-5 { xmi, xma = -0.1, 0.1 } if math.Abs(yma-ymi) < 1e-5 { ymi, yma = -0.1, 0.1 } xx := la.MatAlloc(o.NptsRmp, o.NptsRmp) yy := la.MatAlloc(o.NptsRmp, o.NptsRmp) zz := la.MatAlloc(o.NptsRmp, o.NptsRmp) dx := (xma - xmi) / float64(o.NptsRmp-1) dy := (yma - ymi) / float64(o.NptsRmp-1) for i := 0; i < o.NptsRmp; i++ { for j := 0; j < o.NptsRmp; j++ { xx[i][j] = xmi + float64(i)*dx yy[i][j] = ymi + float64(j)*dy zz[i][j] = xx[i][j] - o.Rmpf(xx[i][j]+yy[i][j]) } } plt.ContourSimple(xx, yy, zz, "colors=['blue'], linewidths=[2], levels=[0]") }
// Determine the symbol that exists at each sample of the signal. func (p Parser) Quantize() { // 0 0011, 3 1100 // 1 0101, 4 1010 // 2 0110, 5 1001 for idx, vec := range p.filtered { argmax := byte(0) max := math.Abs(vec[0]) // If v1 is larger than v0, update max and argmax. if v1 := math.Abs(vec[1]); v1 > max { max = v1 argmax = 1 } // If v2 is larger than the greater of v1 or v0, update max and argmax. if v2 := math.Abs(vec[2]); v2 > max { max = v2 argmax = 2 } // Set the output symbol index. p.quantized[idx] = argmax // If the sign is negative, jump to the index of the inverted symbol. if vec[argmax] > 0 { p.quantized[idx] += 3 } } }
func debug_print_up_results(d *Domain) { io.Pf("\ntime = %23.10f\n", d.Sol.T) for _, v := range d.Msh.Verts { n := d.Vid2node[v.Id] eqpl := n.GetEq("pl") equx := n.GetEq("ux") equy := n.GetEq("uy") var pl, ux, uy float64 if eqpl >= 0 { pl = d.Sol.Y[eqpl] } if equx >= 0 { ux = d.Sol.Y[equx] } if equy >= 0 { uy = d.Sol.Y[equy] } if math.Abs(pl) < 1e-13 { pl = 0 } if math.Abs(ux) < 1e-13 { ux = 0 } if math.Abs(uy) < 1e-13 { uy = 0 } io.Pf("%3d : pl=%23.10v ux=%23.10f uy=%23.10f\n", v.Id, pl, ux, uy) } }
// Horizontal computes data for a horizontal sundial. // // Argument φ is geographic latitude at which the sundial will be located, // a is the length of a straight stylus perpendicular to the plane of the // sundial. // // Results consist of a set of lines, a center point, and u, the length of a // polar stylus. They are in units of a, the stylus length. func Horizontal(φ, a float64) (lines []Line, center Point, u float64) { sφ, cφ := math.Sincos(φ) tφ := sφ / cφ for i := 0; i < 24; i++ { l := Line{Hour: i} H := float64(i-12) * 15 * math.Pi / 180 aH := math.Abs(H) sH, cH := math.Sincos(H) for _, d := range m { tδ := math.Tan(d * math.Pi / 180) H0 := math.Acos(-tφ * tδ) if aH > H0 { continue // sun below horizon } Q := cφ*cH + sφ*tδ x := a * sH / Q y := a * (sφ*cH - cφ*tδ) / Q l.Points = append(l.Points, Point{x, y}) } if len(l.Points) > 0 { lines = append(lines, l) } } center.Y = -a / tφ u = a / math.Abs(sφ) return }
// Vertical computes data for a vertical sundial. // // Argument φ is geographic latitude at which the sundial will be located. // D is gnomonic declination, the azimuth of the perpendicular to the plane // of the sundial, measured from the southern meridian towards the west. // Argument a is the length of a straight stylus perpendicular to the plane // of the sundial. // // Results consist of a set of lines, a center point, and u, the length of a // polar stylus. They are in units of a, the stylus length. func Vertical(φ, D, a float64) (lines []Line, center Point, u float64) { sφ, cφ := math.Sincos(φ) tφ := sφ / cφ sD, cD := math.Sincos(D) for i := 0; i < 24; i++ { l := Line{Hour: i} H := float64(i-12) * 15 * math.Pi / 180 aH := math.Abs(H) sH, cH := math.Sincos(H) for _, d := range m { tδ := math.Tan(d * math.Pi / 180) H0 := math.Acos(-tφ * tδ) if aH > H0 { continue // sun below horizon } Q := sD*sH + sφ*cD*cH - cφ*cD*tδ if Q < 0 { continue // sun below plane of sundial } x := a * (cD*sH - sφ*sD*cH + cφ*sD*tδ) / Q y := -a * (cφ*cH + sφ*tδ) / Q l.Points = append(l.Points, Point{x, y}) } if len(l.Points) > 0 { lines = append(lines, l) } } center.X = -a * sD / cD center.Y = a * tφ / cD u = a / math.Abs(cφ*cD) return }
func (hm HMACMiddleware) checkClockSkew(dateHeaderValue string) bool { // Reference layout for parsing time: "Mon Jan 2 15:04:05 MST 2006" refDate := "Mon, 02 Jan 2006 15:04:05 MST" tim, err := time.Parse(refDate, dateHeaderValue) if err != nil { log.Error("Date parsing failed") return false } inSec := tim.UnixNano() now := time.Now().UnixNano() diff := now - inSec in_ms := diff / 1000000 if math.Abs(float64(in_ms)) > HMACClockSkewLimitInMs { log.Debug("Difference is: ", math.Abs(float64(in_ms))) return false } return true }
func TestGauss(t *testing.T) { src := rand.NewSource(time.Now().Unix()) gen := rand.New(src) // gaussian gaussian := NewDist(128) for i := 0; i < 1000; i++ { v := gen.Intn(200) gaussian.Add(v) } fmt.Println("N-samples:", gaussian.N, ", σ:", gaussian.Sigma) // testing fmt.Println("range [0,200]") sigma := gaussian.Sigma mean := gaussian.Mean for i := 0; i < 10; i++ { v := gen.Intn(200) fmt.Printf("X:%4d: P(v)=%0.4f, deriv:%.2fσ\n", v, gaussian.P(v), math.Abs(float64(v)-mean)/sigma) } fmt.Println("range [0,400]") for i := 0; i < 10; i++ { v := gen.Intn(400) fmt.Printf("X:%4d: P(v)=%0.4f, deriv:%.2fσ\n", v, gaussian.P(v), math.Abs(float64(v)-mean)/sigma) } }
func assertLatLon(t *testing.T, pos Position, doc SampleDoc) { slat, haslat := doc.Result["latitude"].(float64) slon, haslon := doc.Result["longitude"].(float64) if !(haslat && haslon) { return } if math.Abs(pos.Lat-slat) > 0.001 || math.Abs(pos.Lon-slon) > 0.001 { t.Fatalf("Error parsing lat/lon from %v, got %v; expected %v,%v", doc.Src, pos, slat, slon) } tbl := doc.Result["symboltable"].(string)[0] if pos.Symbol.Table != tbl { t.Fatalf("Expected symbol table %v, got %v for %v", tbl, pos.Symbol.Table, doc.Src) } symbol := doc.Result["symbolcode"].(string)[0] if pos.Symbol.Symbol != symbol { t.Fatalf("Expected symbol %v, got %v for %v", symbol, pos.Symbol.Symbol, doc.Src) } course, _ := doc.Result["course"].(float64) assertEpsilon(t, "course of "+doc.Src, course, pos.Velocity.Course) speed, _ := doc.Result["speed"].(float64) assertEpsilon(t, "speed of "+doc.Src, speed, pos.Velocity.Speed) }
// Norm returns the L norm of the slice S, defined as // (sum_{i=1}^N s[i]^L)^{1/L} // Special cases: // L = math.Inf(1) gives the maximum absolute value. // Does not correctly compute the zero norm (use Count). func Norm(s []float64, L float64) float64 { // Should this complain if L is not positive? // Should this be done in log space for better numerical stability? // would be more cost // maybe only if L is high? if len(s) == 0 { return 0 } if L == 2 { twoNorm := math.Abs(s[0]) for i := 1; i < len(s); i++ { twoNorm = math.Hypot(twoNorm, s[i]) } return twoNorm } var norm float64 if L == 1 { for _, val := range s { norm += math.Abs(val) } return norm } if math.IsInf(L, 1) { for _, val := range s { norm = math.Max(norm, math.Abs(val)) } return norm } for _, val := range s { norm += math.Pow(math.Abs(val), L) } return math.Pow(norm, 1/L) }
// Distance computes the L-norm of s - t. See Norm for special cases. // A panic will occur if the lengths of s and t do not match. func Distance(s, t []float64, L float64) float64 { if len(s) != len(t) { panic("floats: slice lengths do not match") } if len(s) == 0 { return 0 } var norm float64 if L == 2 { for i, v := range s { diff := t[i] - v norm = math.Hypot(norm, diff) } return norm } if L == 1 { for i, v := range s { norm += math.Abs(t[i] - v) } return norm } if math.IsInf(L, 1) { for i, v := range s { absDiff := math.Abs(t[i] - v) if absDiff > norm { norm = absDiff } } return norm } for i, v := range s { norm += math.Pow(math.Abs(t[i]-v), L) } return math.Pow(norm, 1/L) }
func TestIntensityMeasuredV1(t *testing.T) { setup() defer teardown() b, err := wt.Request{Accept: V1GeoJSON, URL: "/intensity?type=measured"}.Do(ts.URL) if err != nil { t.Fatal(err) } var i intensityMeasuredV1Features err = json.Unmarshal(b, &i) if err != nil { t.Fatal(err) } if len(i.Features) != 1 { t.Error("found wrong number of intensities.") } if math.Abs(i.Features[0].Geometry.Longitude()-175.49) > tolerance { t.Error("incorrect Longitude") } if math.Abs(i.Features[0].Geometry.Latitude()+40.2) > tolerance { t.Error("incorrect Latitude") } if i.Features[0].Properties.MMI != 4 { t.Error("incorrect MMI") } }
// Ten2Man returns the Mandel representation of a 3x3 2nd order tensor func Ten2Man(mandel []float64, tensor [][]float64) { // check symmetry if math.Abs(tensor[0][1]-tensor[1][0]) > EPS { chk.Panic(_tensor_m1, len(mandel)) } if math.Abs(tensor[1][2]-tensor[2][1]) > EPS { chk.Panic(_tensor_m1, len(mandel)) } if math.Abs(tensor[2][0]-tensor[0][2]) > EPS { chk.Panic(_tensor_m1, len(mandel)) } // convert switch len(mandel) { case 4: if math.Abs(tensor[0][2]) > EPS { chk.Panic(_tensor_m2, tensor[0][2], tensor[1][2]) } if math.Abs(tensor[1][2]) > EPS { chk.Panic(_tensor_m2, tensor[0][2], tensor[1][2]) } mandel[0] = tensor[0][0] mandel[1] = tensor[1][1] mandel[2] = tensor[2][2] mandel[3] = tensor[0][1] * SQ2 case 6: mandel[0] = tensor[0][0] mandel[1] = tensor[1][1] mandel[2] = tensor[2][2] mandel[3] = tensor[0][1] * SQ2 mandel[4] = tensor[1][2] * SQ2 mandel[5] = tensor[2][0] * SQ2 default: chk.Panic(_tensor_oor, "tensor.go: Ten2Man", len(mandel)) } }
// Dasum computes the sum of the absolute values of the elements of x. // \sum_i |x[i]| // Dasum returns 0 if incX is negative. func (Implementation) Dasum(n int, x []float64, incX int) float64 { var sum float64 if n < 0 { panic(negativeN) } if incX < 1 { if incX == 0 { panic(zeroIncX) } return 0 } if incX > 0 && (n-1)*incX >= len(x) { panic(badX) } if incX == 1 { x = x[:n] for _, v := range x { sum += math.Abs(v) } return sum } for i := 0; i < n; i++ { sum += math.Abs(x[i*incX]) } return sum }
func TestCounter(t *testing.T) { db := newDB(t) defer closeDB(db) const key = "127.0.0.1" now := time.Now() n, err := db.incrementCounterInternal(key, 1, now) if err != nil { t.Fatal(err) } if math.Abs(n-1.0) > epsilon { t.Errorf("1: got n=%g, want 1", n) } n, err = db.incrementCounterInternal(key, 1, now) if err != nil { t.Fatal(err) } if math.Abs(n-2.0)/2.0 > epsilon { t.Errorf("2: got n=%g, want 2", n) } now = now.Add(counterHalflife) n, err = db.incrementCounterInternal(key, 1, now) if err != nil { t.Fatal(err) } if math.Abs(n-2.0)/2.0 > epsilon { t.Errorf("3: got n=%g, want 2", n) } }
// FmtFloat yields a string representation of f. E.g. 12345.67 --> "12.3 k"; 0.09876 --> "99 m" func FmtFloat(f float64) string { af := math.Abs(f) if f == 0 { return "0" } else if 1 <= af && af < 10 { return fmt.Sprintf("%.1f", f) } else if 10 <= af && af <= 1000 { return fmt.Sprintf("%.0f", f) } if af < 1 { var p = 8 for math.Abs(f) < 1 && p >= 0 { f *= 1000 p-- } return FmtFloat(f) + Units[p] } else { var p = 7 for math.Abs(f) > 1000 && p < 16 { f /= 1000 p++ } return FmtFloat(f) + Units[p] } return "xxx" }
/* * Compute Givens rotation such that * * G(s,c)*v = (r) == ( c s ).T ( a ) = ( r ) * (0) ( -s c ) ( b ) ( 0 ) * * and * * v*G(s,c) = (r 0 ) == (a b ) ( c s ) = ( r 0 ) * ( -s c ) * */ func ComputeGivens(a, b float64) (c float64, s float64, r float64) { if b == 0.0 { c = 1.0 s = 0.0 r = a } else if a == 0.0 { c = 0.0 s = 1.0 r = b } else if math.Abs(b) > math.Abs(a) { t := a / b u := math.Sqrt(1.0 + t*t) if math.Signbit(b) { u = -u } s = 1.0 / u c = s * t r = b * u } else { t := b / a u := math.Sqrt(1.0 + t*t) r = a * u c = 1.0 / u s = c * t } return }
func vertLerp(iso float32, idx0 uint32, v0 float32, idx1 uint32, v1 float32) (result [3]float32, lerp float32) { edge0 := cube[idx0] edge1 := cube[idx1] switch { case math.Abs(float64(iso-v1)) < 0.00001: result[0] = edge1[0] result[1] = edge1[1] result[2] = edge1[2] lerp = 1.0 return case math.Abs(float64(iso-v0)) < 0.00001, math.Abs(float64(v0-v1)) < 0.00001: result[0] = edge0[0] result[1] = edge0[1] result[2] = edge0[2] lerp = 0.0 return default: lerp = (iso - v0) / (v1 - v0) result[0] = edge0[0] + lerp*(edge1[0]-edge0[0]) result[1] = edge0[1] + lerp*(edge1[1]-edge0[1]) result[2] = edge0[2] + lerp*(edge1[2]-edge0[2]) return } }
func TestStatsTimer(t *testing.T) { s := NewStatsTimer(time.Millisecond, 100) // keep 100 samples var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) x := i + 1 go func() { defer wg.Done() stopWatch := s.Start() time.Sleep(time.Millisecond * time.Duration(x) * 10) s.Stop(stopWatch) }() } // block till all goroutines finish wg.Wait() pctile, err := s.Percentile(100) if math.Abs(pctile-1000) > 5 || err != nil { t.Errorf("Percentile expected: 1000 got: %v", pctile) } pctile, err = s.Percentile(75) if math.Abs(pctile-760) > 5 || err != nil { t.Errorf("Percentile expected: 750 got: %v", pctile) } }
func CanberraDistance(firstVector, secondVector []float64) (float64, error) { distance := 0. for ii := range firstVector { distance += (math.Abs(firstVector[ii]-secondVector[ii]) / (math.Abs(firstVector[ii]) + math.Abs(secondVector[ii]))) } return distance, nil }
func rectApproxEqual(a, b Rect) bool { const epsilon = 1e-15 return math.Abs(a.Lat.Lo-b.Lat.Lo) < epsilon && math.Abs(a.Lat.Hi-b.Lat.Hi) < epsilon && math.Abs(a.Lng.Lo-b.Lng.Lo) < epsilon && math.Abs(a.Lng.Hi-b.Lng.Hi) < epsilon }
func (h *helper) checkConvergence(r *Result, p *Params) Status { if math.Abs(h.gradNorm) < p.FunTolAbs { return GradAbsConv } if math.Abs((h.gradNorm)/h.initialGradNorm) < p.FunTolRel { return GradRelConv } if math.Abs(r.ObjX-h.oldObjX) < p.FunTolAbs { return ObjAbsConv } if math.Abs((r.ObjX-h.oldObjX)/r.ObjX) < p.FunTolRel { return ObjRelConv } h.temp.Sub(r.X, h.oldX) if h.temp.Nrm2() < p.XTolAbs { return XAbsConv } if r.Iter > p.IterMax { return IterLimit } if r.Time > p.TimeMax { return TimeLimit } if r.FunEvals > p.FunEvalMax { return FunEvalLimit } return NotTerminated }
func (hb *Rectangle) intersects(center *terrain.Position, other Hitbox, otherCenter *terrain.Position) (intersects bool, err error) { switch o := other.(type) { case *Rectangle: b1 := hb.bounds(center) b2 := o.bounds(otherCenter) intersects = (b1[0].X <= b2[1].X && b1[1].X >= b2[0].X && b1[0].Y <= b2[1].Y && b1[1].Y >= b2[0].Y) case *Circle: // See http://stackoverflow.com/a/402010 bounds := hb.bounds(center) dx := math.Abs(otherCenter.X - bounds[0].X) dy := math.Abs(otherCenter.Y - bounds[0].Y) if dx > hb.width/2+o.radius || dy > hb.height/2+o.radius { intersects = false } else if dx <= hb.width/2 || dy <= hb.height/2 { intersects = true } else { dc := math.Pow(dx-hb.width/2, 2) + math.Pow(dy-hb.height/2, 2) intersects = (dc <= math.Pow(o.radius, 2)) } default: err = errUnsupportedHitbox } return }
/* KullbackLeiblerDivergence comput and return the divergence of two string based on their character probabability. */ func KullbackLeiblerDivergence(a, b string) (divergence float64) { aCharsd, aValuesd := tekstus.CountAlnumDistribution(a) bCharsd, bValuesd := tekstus.CountAlnumDistribution(b) sumValuesA := numerus.IntsSum(aValuesd) sumValuesB := numerus.IntsSum(bValuesd) charsDiff := tekstus.RunesDiff(aCharsd, bCharsd) aMin, _, _ := numerus.IntsFindMin(aValuesd) bMin, _, _ := numerus.IntsFindMin(bValuesd) min := aMin if bMin < aMin { min = bMin } epsilon := float64(min) * 0.001 gamma := 1.0 - (float64(len(charsDiff)) * epsilon) // Check if sum of a up to 1. var sum float64 for _, v := range aValuesd { sum += float64(v) / float64(sumValuesA) } sumDiff := 1 - math.Abs(sum) if sumDiff > 0.000009 { return 0 } sum = 0 for _, v := range bValuesd { sum += float64(v) / float64(sumValuesB) } sumDiff = 1 - math.Abs(sum) if sumDiff > 0.000009 { return 0 } for x, v := range aCharsd { probA := float64(aValuesd[x]) / float64(sumValuesA) probB := epsilon contain, atIdx := tekstus.RunesContain(bCharsd, v) if contain { probB = gamma * (float64(bValuesd[atIdx]) / float64(sumValuesB)) } divergence += (probA - probB) * math.Log(probA/probB) } return divergence }
// test that brest lat long has close proximity to nearest village func TestBrestVillageProximity(t *testing.T) { var fra Country fra.Name = "fra" fra.NbBodies = 34413 fra.Step = 0 fra.Init() // 48° 23′ 27″ Nord 4° 29′ 08″ Ouest lat := 48.0 + 23.0*1.0/60.0 lng := -4.0 - 29.0*1.0/60.0 // fra.LatLng2XY( lat, lng) x, y, distance, latClosest, lngClosest := fra.VillageCoordinates(lat, lng) deltaLat := math.Abs(latClosest - lat) if deltaLat > 0.1 { // we tolerate one 10th of a degree t.Errorf("Latitude of closest village too far, origin lat %f, village lat %f, delta lat %f, x %d, y %d, distance %f", lat, latClosest, deltaLat, x, y, distance) } deltaLng := math.Abs(lngClosest - lng) if deltaLng > 0.1 { // we tolerate one 10th of a degree t.Errorf("Longitude of closest village too far, origin lng %f, village lng %f, delta lng %f, x %d, y %d, distance %f", lng, lngClosest, deltaLng, x, y, distance) } }
func EqualFloat(x, y, limit float64) bool { if limit <= 0.0 { limit = math.SmallestNonzeroFloat64 } return math.Abs(x-y) <= (limit * math.Min(math.Abs(x), math.Abs(y))) }
func TestQueueSubscriber(t *testing.T) { nc := newConnection(t) defer nc.Close() s1, _ := nc.QueueSubscribeSync("foo", "bar") s2, _ := nc.QueueSubscribeSync("foo", "bar") omsg := []byte("Hello World") nc.Publish("foo", omsg) nc.Flush() r1, r2 := len(s1.mch), len(s2.mch) if (r1 + r2) != 1 { t.Fatal("Received too many messages for multiple queue subscribers") } // Drain messages s1.NextMsg(0) s2.NextMsg(0) total := 1000 for i := 0; i < total; i++ { nc.Publish("foo", omsg) } nc.Flush() v := uint(float32(total) * 0.15) r1, r2 = len(s1.mch), len(s2.mch) if r1+r2 != total { t.Fatalf("Incorrect number of messages: %d vs %d", (r1 + r2), total) } expected := total / 2 d1 := uint(math.Abs(float64(expected - r1))) d2 := uint(math.Abs(float64(expected - r2))) if d1 > v || d2 > v { t.Fatalf("Too much variance in totals: %d, %d > %d", d1, d2, v) } }