// Init initialises the model func (o *RefDecSp1) Init(prms Prms) (err error) { // parameters e := prms.Connect(&o.β, "bet", "ref-dec-sp1 function") e += prms.Connect(&o.λ1, "lam1", "ref-dec-sp1 function") e += prms.Connect(&o.ya, "ya", "ref-dec-sp1 function") e += prms.Connect(&o.yb, "yb", "ref-dec-sp1 function") if e != "" { err = chk.Err("%v\n", e) return } // check if o.yb >= o.ya { return chk.Err("yb(%g) must be smaller than ya(%g)", o.yb, o.ya) } // constants o.c1 = o.β * o.λ1 o.c2 = math.Exp(-o.β * o.ya) o.c3 = math.Exp(-o.β*o.yb) - o.c2 o.c1timestmax = 400 // check if math.IsInf(o.c2, 0) || math.IsInf(o.c3, 0) { return chk.Err("β*ya or β*yb is too large:\n β=%v, ya=%v, yb=%v\n c1=%v, c2=%v, c3=%v", o.β, o.ya, o.yb, o.c1, o.c2, o.c3) } return }
func (v *Voronoi) finishEdge(n *Parabola) { if n.IsLeaf { return } var mx float64 if n.Edge.Direction.X > 0.0 { if v.Width > n.Edge.Start.X+10 { mx = v.Width } else { mx = n.Edge.Start.X + 10 } } else { if 0.0 < n.Edge.Start.X-10 { mx = 0.0 } else { mx = n.Edge.Start.X - 10 } } var end *Point if math.IsInf(float64(n.Edge.F), 1) { end = Pt(mx, v.Height) } else if math.IsInf(float64(n.Edge.F), -1) { end = Pt(mx, 0) } else { end = Pt(mx, mx*n.Edge.F+n.Edge.G) } n.Edge.End = end v.points = append(v.points, end) v.finishEdge(n.Left()) v.finishEdge(n.Right()) }
func (self *_runtime) evaluateDivide(left float64, right float64) Value { if math.IsNaN(left) || math.IsNaN(right) { return NaNValue() } if math.IsInf(left, 0) && math.IsInf(right, 0) { return NaNValue() } if left == 0 && right == 0 { return NaNValue() } if math.IsInf(left, 0) { if math.Signbit(left) == math.Signbit(right) { return positiveInfinityValue() } else { return negativeInfinityValue() } } if math.IsInf(right, 0) { if math.Signbit(left) == math.Signbit(right) { return positiveZeroValue() } else { return negativeZeroValue() } } if right == 0 { if math.Signbit(left) == math.Signbit(right) { return positiveInfinityValue() } else { return negativeInfinityValue() } } return toValue_float64(left / right) }
func TestReadSpecialNumbers(t *testing.T) { assertTrue(t, math.IsNaN(DecodeTransit(t, `"~zNaN"`).(float64))) assertTrue(t, math.IsInf(DecodeTransit(t, `"~zINF"`).(float64), 1)) assertTrue(t, math.IsInf(DecodeTransit(t, `"~z-INF"`).(float64), -1)) VerifyReadError(t, `"~zXYZ"`) }
// formatFloat formats a float the way redis does (sort-of) func formatFloat(v float64) string { // Format with %f and strip trailing 0s. This is the most like Redis does // it :( // .12 is the magic number where most output is the same as Redis. if math.IsInf(v, +1) { return "inf" } if math.IsInf(v, -1) { return "-inf" } sv := fmt.Sprintf("%.12f", v) for strings.Contains(sv, ".") { if sv[len(sv)-1] != '0' { break } // Remove trailing 0s. sv = sv[:len(sv)-1] // Ends with a '.'. if sv[len(sv)-1] == '.' { sv = sv[:len(sv)-1] break } } return sv }
// This function uses the m,b line constants. // If either line is vertical, we use l.From anchor point; there is no need for a l.To point. // The returned bool is true if lines were parallel. // https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection#Given_the_equations_of_the_lines func (l1 LatlongLine) intersectByLineEquations(l2 LatlongLine) (Latlong, bool) { if l1.m == l2.m { return Latlong{}, true } // same slope; are parallel // 1. y=ax+c 2. y=bx+d a, c := l1.m, l1.b b, d := l2.m, l2.b if math.IsInf(a, 0) { // l1 is vertical; x is fixed, take it from the anchor point. Find the point on l2 for that x. x := l1.From.x() y := l2.y(x) return Latlong{y, x}, false } else if math.IsInf(b, 0) { // l2 is vertical; as above, but switch the lines x := l2.From.x() y := l1.y(x) return Latlong{y, x}, false } else { x := (d - c) / (a - b) y := (a*d - b*c) / (a - b) return Latlong{y, x}, false } }
// Norm returns the specified matrix p-norm of the receiver. // // See the Normer interface for more information. func (m *Dense) Norm(ord float64) float64 { var n float64 switch { case ord == 1: col := make([]float64, m.mat.Rows) for i := 0; i < m.mat.Cols; i++ { var s float64 for _, e := range m.Col(col, i) { s += math.Abs(e) } n = math.Max(s, n) } case math.IsInf(ord, +1): row := make([]float64, m.mat.Cols) for i := 0; i < m.mat.Rows; i++ { var s float64 for _, e := range m.Row(row, i) { s += math.Abs(e) } n = math.Max(s, n) } case ord == -1: n = math.MaxFloat64 col := make([]float64, m.mat.Rows) for i := 0; i < m.mat.Cols; i++ { var s float64 for _, e := range m.Col(col, i) { s += math.Abs(e) } n = math.Min(s, n) } case math.IsInf(ord, -1): n = math.MaxFloat64 row := make([]float64, m.mat.Cols) for i := 0; i < m.mat.Rows; i++ { var s float64 for _, e := range m.Row(row, i) { s += math.Abs(e) } n = math.Min(s, n) } case ord == 0: for i := 0; i < len(m.mat.Data); i += m.mat.Stride { for _, v := range m.mat.Data[i : i+m.mat.Cols] { n = math.Hypot(n, v) } } return n case ord == 2, ord == -2: s := SVD(m, epsilon, small, false, false).Sigma if ord == 2 { return s[0] } return s[len(s)-1] default: panic(ErrNormOrder) } return n }
// InitBoundedLog initializes a Histogram instance from the given array // of values with the given number of bins which fall between the given limits. // The logarithms of bin centers are uniformly dist. Any // values outside of these limits are ignored. The returned integer is the // number of such ignored values. Because of this, infinte and non-positive // values do not cause a panic. // // The first returned value is the initialized Histogram. // // InitBoundedLog panics if given a non-positive number of bins or // a low bound as large or larger than the high bound or if given infinite bounds. func (hist *Histogram) InitBoundedLog(xs []float64, binNum int, low, high float64) (*Histogram, int) { if hist.init { panic("stats.Histogram.InitBoundedLog called on initialized struct.") } else if binNum < 1 { panic(fmt.Sprintf("stats.Histogram.InitBoundedLog given binNum of %d", binNum)) } else if low >= high || low <= 0 || math.IsInf(low, 0) || math.IsInf(high, 0) || math.IsNaN(low) || math.IsNaN(high) { panic(fmt.Sprintf("stats.Histogram.InitBoundedLog given range [%d, %d]", low, high)) } hist.init = true hist.Bins = make([]int, binNum) hist.BinValues = make([]float64, binNum) hist.BinEdges = make([]float64, binNum+1) hist.logHistogram = true hist.lowLim = math.Log(low) hist.highLim = math.Log(high) hist.binWidth = (hist.highLim - hist.lowLim) / float64(binNum) for i := 0; i < binNum; i++ { hist.BinEdges[i] = math.Exp(hist.lowLim + hist.binWidth*float64(i)) hist.BinValues[i] = math.Exp(hist.lowLim + hist.binWidth*(float64(i)+0.5)) } hist.BinEdges[binNum] = hist.highLim return hist, hist.AddArray(xs) }
func TestAbs(result, expected, absolute_error float64, test_description string) (status int) { switch { case math.IsNaN(result) || math.IsNaN(expected): status = NaN case math.IsInf(result, 0) || math.IsInf(expected, 0): status = Inf case (expected > 0 && expected < DBL_MIN) || (expected < 0 && expected > -DBL_MIN): status = NotEqual default: if math.Abs(result-expected) > absolute_error { status = NotEqual } else { status = Equal } } if test_description != "" { io.Pf(test_description) switch status { case NaN: io.Pf(" [1;31mNaN[0m\n %v observed\n %v expected. diff = %v\n", result, expected, result-expected) case Inf: io.Pf(" [1;31mInf[0m\n %v observed\n %v expected. diff = %v\n", result, expected, result-expected) case Equal: io.Pf(" [1;32mOk[0m\n %v observed\n %v expected. diff = %v\n", result, expected, result-expected) case NotEqual: io.Pf(" [1;31mError[0m\n %v observed\n %v expected. diff = %v\n", result, expected, result-expected) } } return }
func (h Hermite) FixedLocations(x, weight []float64, min, max float64) { // TODO(btracey): Implement the case where x > 20, x < 200 so that we don't // need to store all of that data. // Algorithm adapted from Chebfun http://www.chebfun.org/. // // References: // Algorithm: // G. H. Golub and J. A. Welsch, "Calculation of Gauss quadrature rules", // Math. Comp. 23:221-230, 1969. // A. Glaser, X. Liu and V. Rokhlin, "A fast algorithm for the // calculation of the roots of special functions", SIAM Journal // on Scientific Computing", 29(4):1420-1438:, 2007. // A. Townsend, T. Trogdon, and S.Olver, Fast computation of Gauss quadrature // nodes and weights on the whole real line, IMA J. Numer. Anal., 36: 337–358, // 2016. http://arxiv.org/abs/1410.5286 if len(x) != len(weight) { panic("hermite: slice length mismatch") } if min >= max { panic("hermite: min >= max") } if !math.IsInf(min, -1) || !math.IsInf(max, 1) { panic("hermite: non-infinite bound") } h.locations(x, weight) }
// String returns a textual representation of r. func (r *Range) String() string { var s string // return empty string if r is nil if r == nil { return s } // begin the string with a "@" if r.complement is set if r.complement { s = "@" } // print the start value unless it's zero (although ranges like @20 are // confusing, make the zero explicit in that case) if math.IsInf(r.start, -1) { s += "~:" } else if r.start != 0 { s += strconv.FormatFloat(r.start, 'f', -1, 64) + ":" } else if r.complement { s += "0:" } // print the end value unless it's +Inf, making sure we don't end up // with an empty string if !math.IsInf(r.end, 1) { s += strconv.FormatFloat(r.end, 'f', -1, 64) } else if len(s) == 0 { s += "0:" } return s }
// generateValidatedLengthExample generates a random size array of examples based on what's given. func (eg *exampleGenerator) generateValidatedLengthExample() interface{} { minlength, maxlength := math.Inf(1), math.Inf(-1) if eg.a.Validation != nil { if eg.a.Validation.MinLength != nil { minlength = float64(*eg.a.Validation.MinLength) } if eg.a.Validation.MaxLength != nil { minlength = float64(*eg.a.Validation.MaxLength) } } count := 0 if math.IsInf(minlength, 1) { count = int(maxlength) - (eg.r.Int() % 3) } else if math.IsInf(maxlength, -1) { count = int(minlength) + (eg.r.Int() % 3) } else if minlength < maxlength { count = int(minlength) + (eg.r.Int() % int(maxlength-minlength)) } else if minlength == maxlength { count = int(minlength) } else { panic("Validation: MinLength > MaxLength") } if !eg.a.Type.IsArray() { return eg.r.faker.Characters(count) } res := make([]interface{}, count) for i := 0; i < count; i++ { res[i] = eg.a.Type.ToArray().ElemType.GenerateExample(eg.r) } return res }
func (this *FunctionCallFirstNum) Evaluate(item *dparval.Value) (*dparval.Value, error) { for _, arg := range this.Operands { av, err := arg.Expr.Evaluate(item) if err != nil { switch err := err.(type) { case *dparval.Undefined: // do NOT return missing continue default: // any other error return to caller return nil, err } } if av.Type() == dparval.NUMBER { num := av.Value().(float64) if !math.IsNaN(num) && !math.IsInf(num, 1) && !math.IsInf(num, -1) { return av, nil } else { continue } } else { continue } } // if all values were +/-Infinity or NaN return NULL return dparval.NewValue(nil), nil }
func (v *Voronoi) getEdgeIntersection(a *Edge, b *Edge) *Point { var ( x = (b.G - a.G) / (a.F - b.F) y = a.F*x + a.G ) if math.IsInf(float64(b.F), 0) { x = b.Start.X y = a.F*x + a.G } if math.IsInf(float64(a.F), 0) { x = a.Start.X y = b.F*x + b.G } if (x-a.Start.X)/a.Direction.X < 0 { return nil } if (y-a.Start.Y)/a.Direction.Y < 0 { return nil } if (x-b.Start.X)/b.Direction.X < 0 { return nil } if (y-b.Start.Y)/b.Direction.Y < 0 { return nil } p := Pt(x, y) v.points = append(v.points, p) return p }
// Round(3.1556,2)=3.16 // Round(3.1556,0)=3 func Round(val float64, places int) float64 { var t float64 f := math.Pow10(places) x := val * f if math.IsInf(x, 0) || math.IsNaN(x) { return val } if x >= 0.0 { t = math.Ceil(x) if (t - x) > 0.50000000001 { t -= 1.0 } } else { t = math.Ceil(-x) if (t + x) > 0.50000000001 { t -= 1.0 } t = -t } x = t / f if !math.IsInf(x, 0) { return x } return t }
// EncodeFloat returns the resulting byte slice with the encoded float64 // appended to b. // // Values are classified as large, medium, or small according to the value of // E. If E is 11 or more, the value is large. For E between 0 and 10, the value // is medium. For E less than zero, the value is small. // // Large positive values are encoded as a single byte 0x22 followed by E as a // varint and then M. Medium positive values are a single byte of 0x17+E // followed by M. Small positive values are encoded as a single byte 0x16 // followed by the ones-complement of the varint for -E followed by M. // // Small negative values are encoded as a single byte 0x14 followed by -E as a // varint and then the ones-complement of M. Medium negative values are encoded // as a byte 0x13-E followed by the ones-complement of M. Large negative values // consist of the single byte 0x08 followed by the ones-complement of the // varint encoding of E followed by the ones-complement of M. func EncodeFloat(b []byte, f float64) []byte { // Handle the simplistic cases first. switch { case math.IsNaN(f): return append(b, floatNaN) case math.IsInf(f, 1): return append(b, floatInfinity) case math.IsInf(f, -1): return append(b, floatNegativeInfinity) case f == 0: return append(b, floatZero) } e, m := floatMandE(b, f) var buf []byte if n := len(m) + maxVarintSize + 2; n <= cap(b)-len(b) { buf = b[len(b) : len(b)+n] } else { buf = make([]byte, len(m)+maxVarintSize+2) } switch { case e < 0: return append(b, encodeSmallNumber(f < 0, e, m, buf)...) case e >= 0 && e <= 10: return append(b, encodeMediumNumber(f < 0, e, m, buf)...) case e >= 11: return append(b, encodeLargeNumber(f < 0, e, m, buf)...) } return nil }
func Qags(ff gsl.F, ab gsl.Interval, eps gsl.Eps, w *WorkSpace) (gsl.Result, error) { // Make a gsl_function var gf C.gsl_function data := gsl.GSLFuncWrapper{ff} gf = C.mkintegCB(unsafe.Pointer(&data)) // Check to see if we have a positive/-negative infinity pinf := math.IsInf(ab.Hi, 1) ninf := math.IsInf(ab.Lo, -1) var ret C.int var y, err C.double // Switch on options switch { case pinf && ninf: ret = C.gsl_integration_qagi(&gf, C.double(eps.Abs), C.double(eps.Rel), C.size_t(w.n), w.w, &y, &err) case pinf: ret = C.gsl_integration_qagiu(&gf, C.double(ab.Lo), C.double(eps.Abs), C.double(eps.Rel), C.size_t(w.n), w.w, &y, &err) case ninf: ret = C.gsl_integration_qagil(&gf, C.double(ab.Hi), C.double(eps.Abs), C.double(eps.Rel), C.size_t(w.n), w.w, &y, &err) default: ret = C.gsl_integration_qags(&gf, C.double(ab.Lo), C.double(ab.Hi), C.double(eps.Abs), C.double(eps.Rel), C.size_t(w.n), w.w, &y, &err) } if ret != 0 { return gsl.Result{float64(y), float64(err)}, gsl.Errno(ret) } return gsl.Result{float64(y), float64(err)}, nil }
// This function exists to manually encode floats. func (ts Timeseries) MarshalJSON() ([]byte, error) { var buffer bytes.Buffer var scratch [64]byte buffer.WriteByte('{') buffer.WriteString("\"tagset\":") tagset, err := json.Marshal(ts.TagSet) if err != nil { return []byte{}, err } buffer.Write(tagset) buffer.WriteByte(',') buffer.WriteString("\"values\":") buffer.WriteByte('[') n := len(ts.Values) for i := 0; i < n; i++ { if i > 0 { buffer.WriteByte(',') } f := ts.Values[i] if math.IsInf(f, 1) { buffer.WriteString("null") // TODO - positive infinity } else if math.IsInf(f, -1) { buffer.WriteString("null") // TODO - negative infinity } else if math.IsNaN(f) { buffer.WriteString("null") } else { b := strconv.AppendFloat(scratch[:0], f, 'g', -1, 64) buffer.Write(b) } } buffer.WriteByte(']') buffer.WriteByte('}') return buffer.Bytes(), err }
func (eg *exampleGenerator) ExampleLength() int { if eg.hasLengthValidation() { minlength, maxlength := math.Inf(1), math.Inf(-1) if eg.a.Validation.MinLength != nil { minlength = float64(*eg.a.Validation.MinLength) } if eg.a.Validation.MaxLength != nil { maxlength = float64(*eg.a.Validation.MaxLength) } count := 0 if math.IsInf(minlength, 1) { count = int(maxlength) - (eg.r.Int() % 3) } else if math.IsInf(maxlength, -1) { count = int(minlength) + (eg.r.Int() % 3) } else if minlength < maxlength { diff := int(maxlength - minlength) if diff > maxExampleLength { diff = maxExampleLength } count = int(minlength) + (eg.r.Int() % diff) } else if minlength == maxlength { count = int(minlength) } else { panic("Validation: MinLength > MaxLength") } if count > maxExampleLength { count = maxExampleLength } if count <= 0 && maxlength != 0 { count = 1 } return count } return eg.r.Int()%3 + 1 }
// generateValidatedLengthExample generates a random size array of examples based on what's given. func (eg *exampleGenerator) generateValidatedLengthExample() interface{} { minlength, maxlength := math.Inf(1), math.Inf(-1) for _, v := range eg.a.Validations { switch actual := v.(type) { case *dslengine.MinLengthValidationDefinition: minlength = math.Min(minlength, float64(actual.MinLength)) maxlength = math.Max(maxlength, float64(actual.MinLength)) case *dslengine.MaxLengthValidationDefinition: minlength = math.Min(minlength, float64(actual.MaxLength)) maxlength = math.Max(maxlength, float64(actual.MaxLength)) } } count := 0 if math.IsInf(minlength, 1) { count = int(maxlength) - (eg.r.Int() % 3) } else if math.IsInf(maxlength, -1) { count = int(minlength) + (eg.r.Int() % 3) } else if minlength < maxlength { count = int(minlength) + (eg.r.Int() % int(maxlength-minlength)) } else if minlength == maxlength { count = int(minlength) } else { panic("Validation: MinLength > MaxLength") } if !eg.a.Type.IsArray() { return eg.r.faker.Characters(count) } res := make([]interface{}, count) for i := 0; i < count; i++ { res[i] = eg.a.Type.ToArray().ElemType.GenerateExample(eg.r) } return res }
// Init initialises the model func (o *RefDecSp1) Init(prms Prms) (err error) { // parameters for _, p := range prms { switch p.N { case "bet": o.β = p.V case "lam1": o.λ1 = p.V case "ya": o.ya = p.V case "yb": o.yb = p.V default: return chk.Err("ref-dec-sp1: parameter named %q is invalid", p.N) } } // check if o.yb >= o.ya { return chk.Err("yb(%g) must be smaller than ya(%g)", o.yb, o.ya) } // constants o.c1 = o.β * o.λ1 o.c2 = math.Exp(-o.β * o.ya) o.c3 = math.Exp(-o.β*o.yb) - o.c2 o.c1timestmax = 400 // check if math.IsInf(o.c2, 0) || math.IsInf(o.c3, 0) { return chk.Err("β*ya or β*yb is too large:\n β=%v, ya=%v, yb=%v\n c1=%v, c2=%v, c3=%v", o.β, o.ya, o.yb, o.c1, o.c2, o.c3) } return }
func isNaT(arr []float64) bool { for _, a := range arr { if a == 0 || math.IsNaN(a) || math.IsInf(a, 1) || math.IsInf(a, -1) { return true } } return arr[2] > (arr[0] + arr[1]) }
func TestNumberConv_Float64(t *testing.T) { assertEquals(NewNumber(50).Float64(), 50.0, t) max := NewNumber(math.MaxFloat64) large := max.Add(max) small := large.Negative() assert(math.IsInf(large.Float64(), 1), "Expected +inf", t) assert(math.IsInf(small.Float64(), -1), "Expected -inf", t) }
// getStartingLocation allocates and initializes the starting location for the minimization. func getStartingLocation(p *Problem, method Method, initX []float64, stats *Stats, settings *Settings) (*Location, error) { dim := len(initX) loc := &Location{ X: make([]float64, dim), } copy(loc.X, initX) if method.Needs().Gradient { loc.Gradient = make([]float64, dim) } if method.Needs().Hessian { loc.Hessian = mat64.NewSymDense(dim, nil) } if settings.UseInitialData { loc.F = settings.InitialValue if loc.Gradient != nil { initG := settings.InitialGradient if initG == nil { panic("optimize: initial gradient is nil") } if len(initG) != dim { panic("optimize: initial gradient size mismatch") } copy(loc.Gradient, initG) } if loc.Hessian != nil { initH := settings.InitialHessian if initH == nil { panic("optimize: initial Hessian is nil") } if initH.Symmetric() != dim { panic("optimize: initial Hessian size mismatch") } loc.Hessian.CopySym(initH) } } else { eval := FuncEvaluation if loc.Gradient != nil { eval |= GradEvaluation } if loc.Hessian != nil { eval |= HessEvaluation } x := make([]float64, len(loc.X)) evaluate(p, loc, eval, stats, x) } if math.IsInf(loc.F, 1) || math.IsNaN(loc.F) { return loc, ErrFunc(loc.F) } for i, v := range loc.Gradient { if math.IsInf(v, 0) || math.IsNaN(v) { return loc, ErrGrad{Grad: v, Index: i} } } return loc, nil }
//ResValue satisfies the Res interface for Num func (n Num) String() string { if math.IsInf(float64(n), 0) { if math.IsInf(float64(n), 1) { return "Infinity" } return "-Infinity" } return fmt.Sprintf("%g", float64(n)) }
func (self _integer) infinity() int { if math.IsInf(float64(self), 0) { if math.IsInf(float64(self), 1) { return +1 } return -1 } return 0 }
// determineDistance will determine the distance between the value // and the target. If the target is positive or negative infinity, // (ie find max or min), this is clamped to max or min float64. func determineDistance(value, target float64) float64 { if math.IsInf(target, 1) { // positive infinity target = math.MaxFloat64 } else if math.IsInf(target, -1) { // negative infinity target = -math.MaxFloat64 } return math.Abs(target - value) }
// Simple 1-step trace. func trace(r Ray, scene []Shape, l Vec3) Vec3 { // index of closest intersecting shape, and distance to it. index := 0 distance := math.Inf(1) for t, shape := range scene { if shape == nil { continue } if sd := shape.RayIntersect(r); sd >= 0 && sd < distance { distance = sd index = t } } if math.IsInf(distance, 0) { // No intersection, return black. return Vec3{} } // Reflect the ray back to the source of light. // We shift r_point by (1-kEps) towards us to avoid effects caused by rounding errors. r_point := Add(r.origin, Mult(distance*(1.0-kEps), r.dir)) light_vec := Sub(l, r_point) light_distance := light_vec.norm() light_dir := Normalize(light_vec) // Check whether we the shadow ray intersects anything. distance = math.Inf(1) for _, shape := range scene { if shape == nil { continue } // If there's an object between us and light source, then alarm! sd := shape.RayIntersect(Ray{r_point, light_dir}) if sd >= 0 && sd < light_distance { distance = sd break } } // We don't want to see the shadows as absolutely dark, therefore allow // some background radiation. bgColor := Mult(kBackgroundRadiation, scene[index].color(r_point)) if !math.IsInf(distance, 0) { // shadow return bgColor } // light return Add( bgColor, Mult((1-kBackgroundRadiation)* math.Abs(DotProduct(light_dir, scene[index].n(r_point))), scene[index].color(r_point))) }
// MarshalJSON exists to manually encode floats. func (ts Timeseries) MarshalJSON() ([]byte, error) { var buffer bytes.Buffer var scratch [64]byte buffer.WriteByte('{') buffer.WriteString("\"tagset\":") tagset, err := json.Marshal(ts.TagSet) if err != nil { return []byte{}, err } buffer.Write(tagset) buffer.WriteByte(',') if ts.Raw != nil { buffer.WriteString("\"raw\":") buffer.WriteByte('[') first := true for _, raw := range ts.Raw { if !first { buffer.WriteByte(',') } buffer.WriteByte('[') buffer.WriteByte('"') base64Wrapped := base64.StdEncoding.EncodeToString(raw) buffer.WriteString(base64Wrapped) buffer.WriteByte('"') buffer.WriteByte(']') first = false } // raw, _ := json.Marshal(ts.Raw) buffer.WriteByte(']') buffer.WriteByte(',') } // buffer.WriteByte(',') buffer.WriteString("\"values\":") buffer.WriteByte('[') n := len(ts.Values) for i := 0; i < n; i++ { if i > 0 { buffer.WriteByte(',') } f := ts.Values[i] if math.IsInf(f, 1) { buffer.WriteString("null") // TODO - positive infinity } else if math.IsInf(f, -1) { buffer.WriteString("null") // TODO - negative infinity } else if math.IsNaN(f) { buffer.WriteString("null") } else { b := strconv.AppendFloat(scratch[:0], f, 'g', -1, 64) buffer.Write(b) } } buffer.WriteByte(']') buffer.WriteByte('}') return buffer.Bytes(), err }
// IsNaN returns true if either real(x) or imag(x) is NaN // and neither is an infinity. func IsNaN(x complex128) bool { switch { case math.IsInf(real(x), 0) || math.IsInf(imag(x), 0): return false case math.IsNaN(real(x)) || math.IsNaN(imag(x)): return true } return false }