func mandelbrotRat(a, b *big.Rat) color.Color { var x, y, nx, ny, x2, y2, f2, f4, r2, tmp big.Rat f2.SetInt64(2) f4.SetInt64(4) x.SetInt64(0) y.SetInt64(0) defer func() { recover() }() for n := uint8(0); n < iterations; n++ { // Not update x2 and y2 // because they are already updated in the previous loop nx.Sub(&x2, &y2) nx.Add(&nx, a) tmp.Mul(&x, &y) ny.Mul(&f2, &tmp) ny.Add(&ny, b) x.Set(&nx) y.Set(&ny) x2.Mul(&x, &x) y2.Mul(&y, &y) r2.Add(&x2, &y2) if r2.Cmp(&f4) > 0 { return color.Gray{255 - contrast*n} } } return color.Black }
func quo(x, y *complexRat) *complexRat { z := newComplexRat() denominator := new(big.Rat) t := new(big.Rat) t.Mul(y.r, y.r) denominator.Mul(y.i, y.i) denominator.Add(denominator, t) if denominator.Cmp(zero) == 0 { return newComplexRat() } ac := new(big.Rat) bd := new(big.Rat) ac.Mul(x.r, y.r) bd.Mul(x.i, y.i) bc := new(big.Rat) ad := new(big.Rat) bc.Mul(x.i, y.r) ad.Mul(x.r, y.i) z.r.Add(ac, bd) z.r.Quo(z.r, denominator) z.i.Add(bc, ad.Neg(ad)) z.i.Quo(z.i, denominator) return z }
func ratProb(mode int) func(*big.Rat) *big.Rat { return func(x *big.Rat) *big.Rat { lo := big.NewInt(0) hi := new(big.Int).Set(big2p63) n := 0 for lo.Cmp(hi) != 0 { m := new(big.Int).Add(lo, hi) m = m.Rsh(m, 1) if n++; n > 100 { fmt.Printf("??? %v %v %v\n", lo, hi, m) break } v := new(big.Rat).SetFrac(m, big2p63) f, _ := v.Float64() v.SetFloat64(f) if v.Cmp(x) < 0 { lo.Add(m, bigOne) } else { hi.Set(m) } } switch mode { default: // case 0 return new(big.Rat).SetFrac(lo, big2p63) case 1: if lo.Cmp(big.NewInt(cutoff1)) <= 0 { lo.Add(lo, big.NewInt(1<<63-cutoff1)) } return new(big.Rat).SetFrac(lo, big2p63) case 2: return new(big.Rat).SetFrac(lo, big.NewInt(cutoff1)) } } }
func BigratToBool(bigrat *big.Rat) bool { cmp := bigrat.Cmp(big.NewRat(0, 1)) if cmp == 0 { return false } else { return true } }
// clampTargetAdjustment returns a clamped version of the base adjustment // value. The clamp keeps the maximum adjustment to ~7x every 2000 blocks. This // ensures that raising and lowering the difficulty requires a minimum amount // of total work, which prevents certain classes of difficulty adjusting // attacks. func clampTargetAdjustment(base *big.Rat) *big.Rat { if base.Cmp(types.MaxAdjustmentUp) > 0 { return types.MaxAdjustmentUp } else if base.Cmp(types.MaxAdjustmentDown) < 0 { return types.MaxAdjustmentDown } return base }
// floatString returns the string representation for a // numeric value v in normalized floating-point format. func floatString(v exact.Value) string { if exact.Sign(v) == 0 { return "0.0" } // x != 0 // convert |v| into a big.Rat x x := new(big.Rat).SetFrac(absInt(exact.Num(v)), absInt(exact.Denom(v))) // normalize x and determine exponent e // (This is not very efficient, but also not speed-critical.) var e int for x.Cmp(ten) >= 0 { x.Quo(x, ten) e++ } for x.Cmp(one) < 0 { x.Mul(x, ten) e-- } // TODO(gri) Values such as 1/2 are easier to read in form 0.5 // rather than 5.0e-1. Similarly, 1.0e1 is easier to read as // 10.0. Fine-tune best exponent range for readability. s := x.FloatString(100) // good-enough precision // trim trailing 0's i := len(s) for i > 0 && s[i-1] == '0' { i-- } s = s[:i] // add a 0 if the number ends in decimal point if len(s) > 0 && s[len(s)-1] == '.' { s += "0" } // add exponent and sign if e != 0 { s += fmt.Sprintf("e%+d", e) } if exact.Sign(v) < 0 { s = "-" + s } // TODO(gri) If v is a "small" fraction (i.e., numerator and denominator // are just a small number of decimal digits), add the exact fraction as // a comment. For instance: 3.3333...e-1 /* = 1/3 */ return s }
// Returns hash if they intersect, otherwise nil func Intersect(P1, Q1, P2, Q2 Vec) ([20]byte, bool) { // Vectors with same length and direction as line segments v1 := Q1.Sub(P1) v2 := Q2.Sub(P2) // Parallel vectors never intersect det := v2.X*v1.Y - v1.X*v2.Y if det == 0 { return sha1nil, false } // Intersection is calculated using linear algebra var k1, k2 big.Rat Pdx, Pdy := P2.X-P1.X, P2.Y-P1.Y invDet := big.NewRat(1, det) k1.Mul(invDet, big.NewRat(-v2.Y*Pdx+v2.X*Pdy, 1)) k2.Mul(invDet, big.NewRat(-v1.Y*Pdx+v1.X*Pdy, 1)) // Check if intersection is inside both segments zero := big.NewRat(0, 1) one := big.NewRat(1, 1) k1valid := k1.Cmp(zero) == 1 && k1.Cmp(one) == -1 k2valid := k2.Cmp(zero) == 1 && k2.Cmp(one) == -1 // Return hash of intersection coordinate if it was if k1valid && k2valid { var Ix, Iy big.Rat Ix.Mul(big.NewRat(v1.X, 1), &k1).Add(&Ix, big.NewRat(P1.X, 1)) Iy.Mul(big.NewRat(v1.Y, 1), &k1).Add(&Iy, big.NewRat(P1.Y, 1)) return sha1.Sum([]byte(fmt.Sprintf("%v,%v", Ix.String(), Iy.String()))), true } else { return sha1nil, false } }
func NewRational(r *big.Rat) Rational { if !r.IsInt() || r.Cmp(min) < 0 || r.Cmp(max) > 0 { return Rational{r} } n := r.Num().Int64() i := n + 256 p := rat[i] if p.v == nil { p = Rational{r} rat[i] = p } return p }
func sqrtFloat(x *big.Rat) *big.Rat { t1 := new(big.Rat) t2 := new(big.Rat) t1.Set(x) // Iterate. // x{n} = (x{n-1}+x{0}/x{n-1}) / 2 for i := 0; i <= 4; i++ { if t1.Cmp(zero) == 0 { return t1 } t2.Quo(x, t1) t2.Add(t2, t1) t1.Mul(half, t2) } return t1 }
func NewRational(r *big.Rat) *Rational { if !r.IsInt() || r.Cmp(min) < 0 || r.Cmp(max) > 0 { return (*Rational)(r) } n := r.Num().Int64() i := n + 256 ratl.RLock() p := rat[i] ratl.RUnlock() if p == nil { p = (*Rational)(r) ratl.Lock() rat[i] = p ratl.Unlock() } return p }
// ratExponent returns the power of ten that x would display in scientific notation. func ratExponent(x *big.Rat) int { if x.Sign() < 0 { x.Neg(x) } e := 0 invert := false if x.Num().Cmp(x.Denom()) < 0 { invert = true x.Inv(x) e++ } for x.Cmp(bigRatBillion) >= 0 { e += 9 x.Quo(x, bigRatBillion) } for x.Cmp(bigRatTen) > 0 { e++ x.Quo(x, bigRatTen) } if invert { return -e } return e }
// EqualBigRat returns true if both *big.Rats are equal func EqualBigRat(a, b *big.Rat) bool { return a.Cmp(b) == 0 }
// MinBigRat returns the smaller of the two *big.Rats func MinBigRat(a, b *big.Rat) *big.Rat { if a.Cmp(b) < 0 { return a } return b }
func binaryFloatOp(x *big.Rat, op token.Token, y *big.Rat) interface{} { var z big.Rat switch op { case token.ADD: return z.Add(x, y) case token.SUB: return z.Sub(x, y) case token.MUL: return z.Mul(x, y) case token.QUO: return z.Quo(x, y) case token.EQL: return x.Cmp(y) == 0 case token.NEQ: return x.Cmp(y) != 0 case token.LSS: return x.Cmp(y) < 0 case token.LEQ: return x.Cmp(y) <= 0 case token.GTR: return x.Cmp(y) > 0 case token.GEQ: return x.Cmp(y) >= 0 } panic("unreachable") }
// Returns the smaller of x or y. func MinBigRat(x, y *big.Rat) *big.Rat { if x.Cmp(y) < 0 { return x } return y }
// Returns the larger of x or y. func MaxBigRat(x, y *big.Rat) *big.Rat { if x.Cmp(y) > 0 { return x } return y }
func backsub(m Matrix) (Vector, error) { if len(m) == 0 || len(m[0]) < 2 { return Vector{}, nil } coeffs := make(Vector, len(m[0])-1) cnts := make([]int, len(m)) for i := range cnts { cnts[i] = -1 } zero := new(big.Rat) for i := range m { nz := 0 l := len(m[i]) - 1 for j := range m[i][:l] { if m[i][j].Cmp(zero) != 0 { nz++ } } if l-nz == l { return nil, fmt.Errorf("contains a zero row") } cnts[i] = nz } z := make([]index, len(cnts)) for i := range z { z[i].r = i z[i].n = cnts[i] } sort.Sort(indexSlice(z)) for i := range z { r := m[z[i].r] l := len(r) - 1 w := new(big.Rat).Set(r[l]) var v *big.Rat for j := range r[:l] { if r[j].Cmp(zero) == 0 { continue } if coeffs[j] != nil { u := new(big.Rat).Set(coeffs[j]) u.Mul(u, r[j]) w.Sub(w, u) } else if v != nil { return nil, fmt.Errorf("matrix not in rref form") } else { v = new(big.Rat).Set(r[j]) } } if v.Cmp(zero) == 0 { return nil, fmt.Errorf("matrix not in rref form") } coeffs[z[i].r] = w.Quo(w, v) } return coeffs, nil }
// Returns a new big.Rat set to maximum of x and y func ratMax(x, y *big.Rat) *big.Rat { if x.Cmp(y) < 1 { return y } return x }
func (a *EqualSplitsAlgorithm) generateBoundaries() ([]tuple, error) { // generateBoundaries should work for a split_column whose type is integral // (both signed and unsigned) as well as for floating point values. // We perform the calculation of the boundaries using precise big.Rat arithmetic and only // truncate the result in the end if necessary. // We do this since using float64 arithmetic does not have enough precision: // for example, if max=math.MaxUint64 and min=math.MaxUint64-1000 then float64(min)==float64(max). // On the other hand, using integer arithmetic for the case where the split_column is integral // (i.e., rounding (max-min)/split_count to an integer) may cause very dissimilar interval // lengths or a large deviation between split_count and the number of query-parts actually // returned (consider min=0, max=9.5*10^6, and split_count=10^6). // Note(erez): We can probably get away with using big.Float with ~64 bits of precision which // will likely be more efficient. However, we defer optimizing this code until we see if this // is a bottle-neck. minValue, maxValue, err := a.executeMinMaxQuery() if err != nil { return nil, err } // If the table is empty, minValue and maxValue will be NULL. if (minValue.IsNull() && !maxValue.IsNull()) || !minValue.IsNull() && maxValue.IsNull() { panic(fmt.Sprintf("minValue and maxValue must both be NULL or both be non-NULL."+ " minValue: %v, maxValue: %v, splitParams.sql: %v", minValue, maxValue, a.splitParams.sql)) } if minValue.IsNull() { log.Infof("Splitting an empty table. splitParams.sql: %v. Query will not be split.", a.splitParams.sql) return []tuple{}, nil } min, err := valueToBigRat(minValue, a.splitParams.splitColumns[0].Type) if err != nil { panic(fmt.Sprintf("Failed to convert min to a big.Rat: %v, min: %+v", err, min)) } max, err := valueToBigRat(maxValue, a.splitParams.splitColumns[0].Type) if err != nil { panic(fmt.Sprintf("Failed to convert max to a big.Rat: %v, max: %+v", err, max)) } minCmpMax := min.Cmp(max) if minCmpMax > 0 { panic(fmt.Sprintf("max(splitColumn) < min(splitColumn): max:%v, min:%v", max, min)) } if minCmpMax == 0 { log.Infof("max(%v)=min(%v)=%v. splitParams.sql: %v. Query will not be split.", a.splitParams.splitColumns[0].Name, a.splitParams.splitColumns[0].Name, min, a.splitParams.sql) return []tuple{}, nil } // subIntervalSize = (max - min) / splitCount maxMinDiff := new(big.Rat) maxMinDiff.Sub(max, min) subIntervalSize := new(big.Rat) subIntervalSize.Quo(maxMinDiff, new(big.Rat).SetInt64(a.splitParams.splitCount)) // If the split-column type is integral then it's wasteful to have a sub-intervale-size smaller // than 1, as it'll result with some query-parts being trivially empty. We set the // sub-interval size to 1 in this case. one := new(big.Rat).SetInt64(1) if sqltypes.IsIntegral(a.splitParams.splitColumns[0].Type) && subIntervalSize.Cmp(one) < 0 { subIntervalSize = one } boundary := new(big.Rat).Add(min, subIntervalSize) result := []tuple{} for ; boundary.Cmp(max) < 0; boundary.Add(boundary, subIntervalSize) { boundaryValue := bigRatToValue(boundary, a.splitParams.splitColumns[0].Type) result = append(result, tuple{boundaryValue}) } return result, nil }
// MaxBigRat returns the larger of the two *big.Rats func MaxBigRat(a, b *big.Rat) *big.Rat { if a.Cmp(b) > 0 { return a } return b }
// Returns a new big.Rat set to minimum of x and y func ratMin(x, y *big.Rat) *big.Rat { if x.Cmp(y) > 0 { return y } return x }
func isZero(q big.Rat) bool { return q.Cmp(&zero) == 0 }
func checkRats(expected *big.Rat, result *big.Rat, t *testing.T) { if expected.Cmp(result) != 0 { t.Errorf("Expected: %s\nResult: %s\n", expected, result) } }