// Random gamma variable when shape<1 // See Kundu and Gupta 2007 // "A convenient way of generating gamma random variables using generalized exponential distribution" func (rg RandGen) rgamma2(shape float64) float64 { if shape <= 0.0 || shape >= 1.0 { panic("Illegal parameter. Shape must be positive and no greater than one") } d := 1.0334 - 0.0766*math.Exp(2.2942*shape) // Constants from paper a := math.Exp2(shape) * math.Pow(-math.Expm1(-d/2), shape) pdsh := math.Pow(d, shape-1.0) b := shape * pdsh * math.Exp(-d) c := a + b start: u := rg.Float64() var x float64 if u <= a/c { x = -2.0 * math.Log1p(-math.Pow(c*u, 1.0/shape)/2.0) } else { x = -math.Log(c * (1.0 - u) / (shape * pdsh)) } v := rg.Float64() if x <= d { p := math.Pow(x, shape-1.0) * math.Exp(-x/2.0) / (math.Exp2(shape-1.0) * math.Pow(-math.Expm1(-x/2.0), shape-1.0)) if v > p { goto start } } else { if v > math.Pow(d/x, 1.0-shape) { goto start } } return x }
// Rescore recalculates the scores based on the current guests. func (t *Table) Rescore(p Prefs) { var left, right int for _, g := range t.Left { if g.Name != "" { left++ } } for _, g := range t.Right { if g.Name != "" { right++ } } t.TableScore = 0 t.TableScore += CapacityPref * math.Expm1(math.Abs(float64( (len(t.Left)+len(t.Right)-2)-(left+right)))) t.TableScore += ImbalancePref * math.Expm1(math.Abs(float64(left-right))) t.scoreSide(t.Left, t.Right, t.LeftScores, p) t.scoreSide(t.Right, t.Left, t.RightScores, p) t.Score = t.TableScore for _, s := range t.LeftScores { if s != 0 { t.Score += s } } for _, s := range t.RightScores { if s != 0 { t.Score += s } } }
func main() { for true { r := bufio.NewReader(os.Stdin) s, err := r.ReadString('\n') if err == os.EOF { break } s = strings.TrimRight(s, "\n") a := strings.Split(s, " ") f := a[0] x, err := strconv.Atof64(a[1]) switch f { case "erf": fmt.Println(math.Erf(x)) case "expm1": fmt.Println(math.Expm1(x)) case "phi": fmt.Println(phi.Phi(x)) case "NormalCDFInverse": fmt.Println(normal_cdf_inverse.NormalCDFInverse(x)) case "Gamma": fmt.Println(math.Gamma(x)) case "LogGamma": r, _ := math.Lgamma(x) fmt.Println(r) case "LogFactorial": fmt.Println(log_factorial.LogFactorial(int(x))) default: fmt.Println("Unknown function: " + f) return } } }
// Calculate U_{2}/N = 1/N \sum_k (\omega_+(k) + \mu_b) n_b(\omega_+(k)) func PairEnergy(env *tempAll.Environment) (float64, error) { // find omega_+ coefficients a, b := env.A, env.B if !env.FixedPairCoeffs || !env.PairCoeffsReady { plusCoeffs, err := OmegaFit(env, OmegaPlus) if err != nil { fmt.Println("suppressing error in PairEnergy - cannot find pair spectrum") return 0.0, nil } a, b = plusCoeffs[0], plusCoeffs[2] } // kz^2 version - incompatible with finite magnetic field if env.PairKzSquaredSpectrum && math.Abs(env.Be_field) < 1e-9 { integrand := func(y float64) float64 { num := math.Pow(y, 1.5) denom := math.Exp(y-env.Beta*env.Mu_b) - 1.0 return num / denom } integral, err := OmegaIntegralY(env, a, b, integrand) if err != nil { return 0.0, err } return integral / math.Pow(env.Beta, 2.5), nil } // cos(kz) version if math.Abs(env.Be_field) < 1e-9 { integrand := func(y, kz float64) float64 { bterm := 2.0 * b * (1.0 - math.Cos(kz)) num := y/env.Beta + bterm denom := math.Exp(y+env.Beta*(bterm-env.Mu_b)) - 1.0 return num / denom } integral, err := OmegaIntegralCos(env, a, b, integrand) if err != nil { return 0.0, err } return integral, nil } // if we get here, math.Abs(env.Be_field) >= 1e-9 //fmt.Printf("about to calculate E2 B sum for env = %s\n", env.String()) E2BSumTerm := func(ri int) float64 { r := float64(ri) I0 := bessel.ModifiedBesselFirstKindZeroth(2.0 * b * env.Beta * r) I1 := bessel.ModifiedBesselFirstKindFirst(2.0 * b * env.Beta * r) omega_c := 4.0 * env.Be_field * a mu_tilde := env.Mu_b - omega_c/2.0 expL := math.Exp(r * env.Beta * (mu_tilde - 2.0*b)) expR := math.Exp(-env.Beta * omega_c * r) expm1 := -math.Expm1(-env.Beta * omega_c * r) return expL * ((I0*(0.5+2.0*b)-2.0*b*I1)*expm1 + (I0 * omega_c * expR * expm1 * expm1)) } sum, _ := seriesaccel.Levin_u(E2BSumTerm, 1, 20) // reporting of absErr: // (dropped this since absErr is always very small compared to sum) //sum, absErr := seriesaccel.Levin_u(E2BSumTerm, 1, 20) //fmt.Printf("env=%s; E2 B sum %e, absErr %e\n", env.String(), sum, absErr) return 2.0 * env.Be_field * sum / math.Pi, nil }
// Magnetization per unit area divided by e func Magnetization(env *tempAll.Environment) (float64, error) { if math.Abs(env.Be_field) < 1e-9 { return 0.0, nil } if -env.Mu_b > -2.0*env.Mu_h { return 0.0, nil } // find omega_+ coefficients a, b := env.A, env.B if !env.FixedPairCoeffs || !env.PairCoeffsReady { plusCoeffs, err := OmegaFit(env, OmegaPlus) //fmt.Printf("plusCoeffs in Magnetization: %v\n", plusCoeffs) if err != nil { fmt.Println("suppressing error in magnetization - cannot find pair spectrum") return 0.0, nil } a, b = plusCoeffs[0], plusCoeffs[2] } MSumTerm := func(ri int) float64 { r := float64(ri) I0 := bessel.ModifiedBesselFirstKindZeroth(2.0 * b * env.Beta * r) omega_c := 4.0 * env.Be_field * a mu_tilde := env.Mu_b - omega_c/2.0 exp := -math.Expm1(-r * env.Beta * omega_c) bracket := 1.0/(env.Beta*r*exp) - omega_c*math.Exp(-r*env.Beta*omega_c)/(exp*exp) return I0 * math.Exp(r*env.Beta*(mu_tilde-2.0*b)) * bracket /* bracket_num_term := func(ni int) float64 { n := float64(ni) nm1_fact := math.Gamma(n) return -math.Pow(-r * env.Beta * omega_c, n + 1.0) / ((n + 1.0) * nm1_fact) } bracket_denom_term := func(ni int) float64 { n := float64(ni) n_fact := math.Gamma(n + 1.0) return math.Pow(-r * env.Beta * omega_c, n) * (math.Pow(2.0, n - 1.0) - 1.0) / n_fact } bracket_num, _ := seriesaccel.Levin_u(bracket_num_term, 1, 20) bracket_denom, _ := seriesaccel.Levin_u(bracket_denom_term, 2, 20) return I0 * math.Exp(r*env.Beta*(mu_tilde-2.0*b)) * bracket_num / (2.0 * bracket_denom) */ } //sum, absErr := seriesaccel.Levin_u(MSumTerm, 1, 20) //fmt.Printf("Magnetization sum %e, absErr %e\n", sum, absErr) sum, _ := seriesaccel.Levin_u(MSumTerm, 1, 20) x2, err := X2(env) if err != nil { return 0.0, err } return -a*x2 + sum/math.Pi, nil //return -a*x2 - sum/math.Pi, nil }
func TestScoring(t *testing.T) { table := saseat.NewTable(8) table.Left[0] = saseat.Guest{"Abe", "male"} table.Left[1] = saseat.Guest{"Mary", "female"} table.Left[2] = saseat.Guest{"Jane", "female"} table.Right[0] = saseat.Guest{"Alexander", "male"} table.Right[1] = saseat.Guest{"Kang", ""} expectedTableScore := saseat.CapacityPref*math.Expm1(1) + saseat.ImbalancePref*math.Expm1(1) prefs := saseat.Prefs{} prefs.Set("Abe", "Mary", 1000) prefs.Set("Kang", "Jane", -80) prefs.Set("Alexander", "Jane", 50) expectedLeft := []float64{ 1000 * saseat.AdjacentWeight, 1000*saseat.AdjacentWeight + saseat.SameGenderPref, -80*saseat.DiagonalWeight + 50*saseat.SameTableWeight + saseat.SameGenderPref, 0, } expectedRight := []float64{ 50 * saseat.SameTableWeight, -80 * saseat.DiagonalWeight, 0, 0, } table.Rescore(prefs) if table.TableScore != expectedTableScore { t.Errorf("got table score %v, want %v", table.TableScore, expectedTableScore) } if !reflect.DeepEqual(table.LeftScores, expectedLeft) { t.Errorf("got left prefs %v, want %v", table.LeftScores, expectedLeft) } if !reflect.DeepEqual(table.RightScores, expectedRight) { t.Errorf("got right prefs %v, want %v", table.RightScores, expectedRight) } }
func leaving(matrix [][]float64, coeff []float64, basic []int, enter int) int { leave := -2 currentConstraint := math.Expm1(64) for i, v := range matrix { if v[enter] < 0 { if q := coeff[i] / -(v[enter]); leave >= 0 && q == currentConstraint { if basic[i] < basic[leave] { leave = i } } else if q < currentConstraint { currentConstraint = q leave = i } } } return leave }
// Concentration of paired holons func X2(env *tempAll.Environment) (float64, error) { // kz^2 version - incompatible with finite magnetic field if env.PairKzSquaredSpectrum && math.Abs(env.Be_field) < 1e-9 { nu, err := nu(env) if err != nil { return 0.0, err } x2 := nu / math.Pow(env.Beta, 3.0/2.0) return x2, nil } // cos(kz) version if -env.Mu_b > -2.0*env.Mu_h { return 0.0, nil } // find omega_+ coefficients a, b := env.A, env.B if !env.FixedPairCoeffs || !env.PairCoeffsReady { plusCoeffs, err := OmegaFit(env, OmegaPlus) //fmt.Printf("plusCoeffs in X2: %v\n", plusCoeffs) if err != nil { fmt.Println("suppressing error in x2 - cannot find pair spectrum") return 0.0, nil } a, b = plusCoeffs[0], plusCoeffs[2] } // zero magnetic field with cos(kz) spectrum if math.Abs(env.Be_field) < 1e-9 { integrand := func(y, kz float64) float64 { bterm := 2.0 * b * (1.0 - math.Cos(kz)) return 2.0 / (math.Exp(y+env.Beta*(bterm-env.Mu_b)) - 1.0) } plus, err := OmegaIntegralCos(env, a, b, integrand) if err != nil { return 0.0, err } return plus, nil } // if we get here, math.Abs(env.Be_field) >= 1e-9 //fmt.Printf("about to calculate x2 sum for env = %s\n", env.String()) x2BSumTerm := func(ri int) float64 { r := float64(ri) I0 := bessel.ModifiedBesselFirstKindZeroth(2.0 * b * env.Beta * r) omega_c := 4.0 * env.Be_field * a mu_tilde := env.Mu_b - omega_c/2.0 return I0 * math.Exp(env.Beta*r*(mu_tilde-2.0*b)) / (-math.Expm1(-env.Beta * omega_c * r)) /* sum_n_term := func(ni int) float64 { n := float64(ni) np1_fact := math.Gamma(n + 2.0) return math.Pow(-r * env.Beta * omega_c, n) / np1_fact } sum_n, _ := seriesaccel.Levin_u(sum_n_term, 1, 20) return I0 * math.Exp(env.Beta*r*(mu_tilde-2.0*b)) / (r * (1.0 + sum_n)) */ } sum, _ := seriesaccel.Levin_u(x2BSumTerm, 1, 20) //fmt.Printf("%v\n", sum) // reporting of absErr: // (dropped this since absErr is always very small relative to sum) //sum, absErr := seriesaccel.Levin_u(x2BSumTerm, 1, 20) //fmt.Printf("for env=%s; x2 B sum %e, absErr %e\n", env.String(), sum, absErr) return 2.0 * env.Be_field * sum / math.Pi, nil //return sum / (2.0 * math.Pi * env.Beta * a), nil }
func ext۰math۰Expm1(fr *Frame, args []Value) Value { return math.Expm1(args[0].(float64)) }
// float32 version of math.Expm1f func Expm1(x float32) float32 { return float32(math.Expm1(float64(x))) }