github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/physicscompress2/optimizer.go (about) 1 package main 2 3 import ( 4 "encoding/gob" 5 "flag" 6 "fmt" 7 "math/rand" 8 "os" 9 "time" 10 11 "github.com/egonelbre/exp/bit" 12 "github.com/egonelbre/exp/coder/arith" 13 "github.com/egonelbre/exp/physicscompress2/physics" 14 ) 15 16 func check(err error) { 17 if err != nil { 18 panic(err) 19 } 20 } 21 22 var ( 23 tries = flag.Int("tries", 1e6, "how many random tries should it make") 24 ) 25 26 func RandomModel() (m1, m2 arith.Model, desc string) { 27 switch rand.Intn(1) { 28 case 0: 29 x1 := arith.Shift2{ 30 P0: arith.P(rand.Intn(arith.MaxP / 2)), 31 I0: byte(rand.Intn(8) + 1), 32 P1: arith.P(rand.Intn(arith.MaxP / 2)), 33 I1: byte(rand.Intn(8) + 1), 34 } 35 x2 := x1 36 m1, m2 = &x1, &x2 37 case 1: 38 x1 := arith.Shift4{ 39 P: [4]arith.P{ 40 arith.P(rand.Intn(arith.MaxP / 4)), 41 arith.P(rand.Intn(arith.MaxP / 4)), 42 arith.P(rand.Intn(arith.MaxP / 4)), 43 arith.P(rand.Intn(arith.MaxP / 4)), 44 }, 45 I: [4]byte{ 46 byte(rand.Intn(7) + 1), 47 byte(rand.Intn(7) + 1), 48 byte(rand.Intn(7) + 1), 49 byte(rand.Intn(7) + 1), 50 }, 51 } 52 x2 := x1 53 m1, m2 = &x1, &x2 54 } 55 desc = fmt.Sprintf("%#v", m1) 56 return 57 } 58 59 func RandomTree(nbits uint) (m1 arith.Model, desc string) { 60 x1 := arith.Shift2{ 61 P0: arith.P(rand.Intn(arith.MaxP / 2)), 62 I0: byte(rand.Intn(8) + 1), 63 P1: arith.P(rand.Intn(arith.MaxP / 2)), 64 I1: byte(rand.Intn(8) + 1), 65 } 66 67 m1 = arith.NewTree(nbits, func() arith.Model { 68 x := x1 69 return &x 70 }) 71 72 desc = fmt.Sprintf("%#v", x1) 73 return 74 } 75 76 func main() { 77 flag.Parse() 78 79 rand.Seed(time.Now().UnixNano()) 80 81 var baseline []physics.Cube 82 var current []physics.Cube 83 84 file, err := os.Open(flag.Arg(0)) 85 check(err) 86 87 dec := gob.NewDecoder(file) 88 dec.Decode(¤t) 89 dec.Decode(&baseline) 90 91 minimal := 1 << 10 92 93 items := []int{} 94 for i := range current { 95 cube, base := ¤t[i], &baseline[i] 96 if *cube != *base { 97 items = append(items, i) 98 } 99 } 100 101 items6 := physics.Index6(items, len(current)) 102 cur6 := physics.Delta6(baseline, current) 103 max := uint64(0) 104 for _, i := range items6 { 105 ext := uint64(bit.ZEncode(int64(cur6(i)))) 106 if max < ext { 107 max = ext 108 } 109 } 110 111 nbits := bit.ScanRight(max) + 1 112 113 for i := 0; i < *tries; i += 1 { 114 menc, desc := RandomTree(nbits) 115 enc := arith.NewEncoder() 116 117 for _, i := range items { 118 cube := ¤t[i] 119 menc.Encode(enc, uint(cube.Interacting^1)) 120 } 121 122 for _, i := range items { 123 cube, base := ¤t[i], &baseline[i] 124 v := uint(cube.Largest ^ base.Largest) 125 menc.Encode(enc, v&1) 126 menc.Encode(enc, v>>1) 127 } 128 129 enc.Close() 130 131 if len(enc.Bytes()) < minimal { 132 fmt.Printf("%6d %5d - %s\n", i, len(enc.Bytes()), desc) 133 minimal = len(enc.Bytes()) 134 } 135 } 136 }