From 10f1dc35a1f4965cdc61b2d77880d25e3897243c Mon Sep 17 00:00:00 2001 From: kpmy Date: Wed, 9 Sep 2015 00:00:54 +0300 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=89?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=88=D0=B0=D0=B3=D0=B8,=20=D0=B7=D0=B0=D0=B3?= =?UTF-8?q?=D1=80=D1=83=D0=B7=D0=BA=D0=B0=20=D0=B2=D1=8B=D0=B3=D1=80=D1=83?= =?UTF-8?q?=D0=B7=D0=BA=D0=B0=20=D1=81=D0=B5=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gone.in/main.go | 232 -------------------------------- {gone.in => gone.to}/circle.png | Bin gone.to/main.go | 120 +++++++++++------ {gone.in => gone.to}/square.png | Bin link.go | 189 -------------------------- model.go | 38 ------ perc/model.go | 2 +- perc/std/sm.go | 56 ++++++++ 8 files changed, 134 insertions(+), 503 deletions(-) delete mode 100644 gone.in/main.go rename {gone.in => gone.to}/circle.png (100%) rename {gone.in => gone.to}/square.png (100%) delete mode 100644 link.go delete mode 100644 model.go create mode 100644 perc/std/sm.go diff --git a/gone.in/main.go b/gone.in/main.go deleted file mode 100644 index d6a6724..0000000 --- a/gone.in/main.go +++ /dev/null @@ -1,232 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "github.com/kpmy/ypk/halt" - "gone" - "io" - "log" - "math/rand" - "os" - "reflect" - "strconv" - "strings" - "sync" - "time" -) - -var debug bool - -func init() { - log.SetFlags(0) - debug = false -} - -func pre(p *gone.Perc) { - const ( - Nsens = 256 * 256 - Msens = 16 - Nass = 1024 - Nreact = 2 - ) - rnd := rand.New(rand.NewSource(time.Now().UnixNano())) - p.Sens = nil - var socache []*gone.Out - for i := 0; i < Nsens; i++ { - next := &gone.Sens{Id: "s." + strconv.Itoa(i)} - outs := make([]*gone.Out, rnd.Intn(Msens)+1) - for j := 0; j < len(outs); j++ { - w := 0 - if rnd.Intn(2) == 0 { - w = 1 - } else { - w = -1 - } - outs[j] = &gone.Out{Id: strconv.Itoa(j), Owner: next.Id, Weight: w} - next.Out = outs - } - socache = append(socache, outs...) - p.Sens = append(p.Sens, next) - } - p.Ass = nil - var aocache []*gone.Out - for i := 0; i < Nass; i++ { - next := &gone.Ass{Id: "a." + strconv.Itoa(i)} - next.In = &gone.In{} - outs := make([]*gone.Out, rnd.Intn(Nreact)+1) - for j := 0; j < len(outs); j++ { - outs[j] = &gone.Out{Id: strconv.Itoa(j), Owner: next.Id, Weight: rnd.Intn(201) - 100} - next.Out = outs - } - aocache = append(aocache, outs...) - p.Ass = append(p.Ass, next) - } - { - acache := make(map[string]map[string]interface{}) - j := 0 - for i := 0; i < len(socache); { - r := socache[i] - skip := false - if _, ok := acache[p.Ass[j].Id]; ok { - if _, ok := acache[p.Ass[j].Id][r.Owner]; ok { - skip = true - j++ - if j == len(p.Ass) { - j = 0 - } - } - } - if !skip { - p.Ass[j].In.Io = append(p.Ass[j].In.Io, r) - if _, ok := acache[p.Ass[j].Id]; !ok { - acache[p.Ass[j].Id] = make(map[string]interface{}) - } - acache[p.Ass[j].Id][r.Owner] = r - i++ - } - } - } - p.React = nil - for i := 0; i < Nreact; i++ { - next := &gone.React{Id: "r." + strconv.Itoa(i)} - next.In = &gone.In{} - next.Out = &gone.Out{Owner: next.Id, Id: "0"} - p.React = append(p.React, next) - } - { - rcache := make(map[string]map[string]interface{}) - j := 0 - for i := 0; i < len(aocache); { - r := aocache[i] - skip := false - if _, ok := rcache[p.React[j].Id]; ok { - if _, ok := rcache[p.React[j].Id][r.Owner]; ok { - skip = true - j++ - if j == len(p.React) { - j = 0 - } - } - } - if !skip { - p.React[j].In.Io = append(p.React[j].In.Io, r) - if _, ok := rcache[p.React[j].Id]; !ok { - rcache[p.React[j].Id] = make(map[string]interface{}) - } - rcache[p.React[j].Id][r.Owner] = r - i++ - } - } - } - if debug { - var dump func(*gone.In, string) - dump = func(in *gone.In, indent string) { - for _, r := range in.Io { - log.Println(indent, r.Owner+":"+r.Id) - } - } - - for _, r := range p.Ass { - log.Println(r.Id) - dump(r.In, " ") - } - - for _, r := range p.React { - log.Println(r.Id) - dump(r.In, " ") - } - } -} - -func do(m map[string]*gone.Node, data []int) (ret map[string]int) { - dataFor := func(id string) int { - if x, err := strconv.Atoi(strings.TrimPrefix(strings.TrimSuffix(id, ":0"), "s.")); err == nil { - return data[x] - } else { - halt.As(100, err) - } - panic(0) - } - type pack struct { - id string - c int - } - wg := new(sync.WaitGroup) - rg := new(sync.WaitGroup) - ret = make(map[string]int) - res := make(chan pack) - wg.Add(1) - - go func() { - for c := range res { - ret[c.id] = c.c - } - wg.Done() - }() - - for _, n := range m { - switch o := n.Obj.(type) { - case *gone.Sens: - wg.Add(1) - go func(n *gone.Node, c int) { - n.In[0].Write(c) - wg.Done() - }(n, dataFor(o.Id)) - case *gone.React: - wg.Add(1) - rg.Add(1) - go func(n *gone.Node) { - res <- pack{id: o.Id, c: n.Out[0].Read()} - wg.Done() - rg.Done() - }(n) - case *gone.Ass: - //do nothing - default: - halt.As(100, reflect.TypeOf(o)) - } - } - go func() { - rg.Wait() - close(res) - }() - wg.Wait() - return -} - -func main() { - p := &gone.Perc{} - if f, err := os.Open("demo-0.pc"); err == nil { - buf := bytes.NewBuffer(nil) - io.Copy(buf, f) - json.Unmarshal(buf.Bytes(), p) - f.Close() - } else { - pre(p) - } - pre(p) //debug only - - var m interface{} - m = do(gone.Load(p), []int{ - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 1, 1, 1, 1, 1, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0}) - log.Println("+", m) - - m = do(gone.Load(p), []int{ - 1, 0, 0, 0, 1, - 0, 1, 0, 1, 0, - 0, 0, 1, 0, 0, - 0, 1, 0, 1, 0, - 1, 0, 0, 0, 1}) - - log.Println("x", m) - if f, err := os.Create("demo-0.pc"); err == nil { - buf, _ := json.MarshalIndent(p, "", " ") - f.Write(buf) - f.Close() - } -} diff --git a/gone.in/circle.png b/gone.to/circle.png similarity index 100% rename from gone.in/circle.png rename to gone.to/circle.png diff --git a/gone.to/main.go b/gone.to/main.go index 706eb38..6d2ee03 100644 --- a/gone.to/main.go +++ b/gone.to/main.go @@ -1,14 +1,18 @@ package main import ( + "encoding/json" "github.com/kpmy/ypk/assert" "gone/perc" + "gone/perc/std" + "io" "log" "math/rand" + "os" ) const ( - Nsens = 256 * 256 + Nsens = 64 * 64 MaxSensOut = 128 Nass = 256 Nreact = 16 @@ -19,57 +23,71 @@ func init() { log.SetFlags(0) } -func New(nn, no int, w_fn func() int) (ret *model.Layer) { - ret = &model.Layer{} - for i := 0; i < nn; i++ { - next := model.NewNode() - next.Out = make([]interface{}, rand.Intn(no)+1) - next.Weights = make([]int, len(next.Out)) - if w_fn != nil { - for i := 0; i < len(next.Weights); i++ { - next.Weights[i] = w_fn() +type Link struct { + NodeId int `json:"node"` + LinkId int `json:"out"` +} + +type NodeStruct struct { + Outs []int `json:"out"` + Ins []Link `json:"in,omitempty"` +} + +type LayerStruct struct { + Nodes []*NodeStruct `json:"node"` +} + +func Store(wr io.Writer, first *model.Layer) error { + res := make([]*LayerStruct, 0) + for l := first; l != nil; l = l.Next { + next := &LayerStruct{} + for _, n := range l.Nodes { + node := &NodeStruct{} + for _, w := range n.Weights { + node.Outs = append(node.Outs, w) + } + for k, _ := range n.In { + link := Link{NodeId: k.NodeId, LinkId: k.LinkId} + node.Ins = append(node.Ins, link) } + next.Nodes = append(next.Nodes, node) } - ret.Nodes = append(ret.Nodes, next) + res = append(res, next) } - return + return json.NewEncoder(wr).Encode(res) } -func Join(in *model.Layer, out *model.Layer) { - j := 0 - type im map[int]interface{} - cache := make([]im, len(out.Nodes)) - for k, n := range in.Nodes { - for i := 0; i < len(n.Out); { - assert.For(len(n.Out) <= len(out.Nodes), 20, len(n.Out), len(out.Nodes)) - l := model.Link{NodeId: k, LinkId: i} - skip := false - if cache[j] != nil { - if _, ok := cache[j][k]; ok { - skip = true - j++ - if j == len(cache) { - j = 0 - } - } +func Load(rd io.Reader) (ret *model.Layer, err error) { + ll := make([]LayerStruct, 0) + if err = json.NewDecoder(rd).Decode(ll); err == nil { + var this *model.Layer + for _, l := range ll { + if ret == nil { + this = &model.Layer{} + ret = this + } else { + this.Next = &model.Layer{} + this = this.Next } - if !skip { - out.Nodes[j].In[l] = nil - if cache[j] == nil { - cache[j] = make(im) + for _, n := range l.Nodes { + node := model.NewNode() + for _, w := range n.Outs { + node.Weights = append(node.Weights, w) } - cache[j][k] = l - //log.Println(l, "to", j) - i++ + node.Out = make([]interface{}, len(node.Weights)) + for _, l := range n.Ins { + link := model.Link{LinkId: l.LinkId, NodeId: l.NodeId} + node.In[link] = nil + } + this.Nodes = append(this.Nodes, node) } - //log.Println(k, len(n.Out), i, j) } } - in.Next = out + return } func main() { - s := New(Nsens, MaxSensOut, func() int { + s := std.New(Nsens, MaxSensOut, func() int { x := rand.Intn(2) if x == 0 { return 1 @@ -77,9 +95,25 @@ func main() { return -1 } }) - a := New(Nass, Nreact, func() int { return rand.Intn(201) - 100 }) - r := New(Nreact, 1, nil) + a := std.New(Nass, Nreact, func() int { return rand.Intn(201) - 100 }) + r := std.New(Nreact, 1, nil) + + std.Join(s, a) + std.Join(a, r) + + log.Println(s) + + if f, err := os.Create("0.pc"); err == nil { + Store(f, s) + f.Close() + } + + if f, err := os.Open("0.pc"); err == nil { + if s, err = Load(f); err != nil { + log.Fatal(err) + } + f.Close() + } - Join(s, a) - Join(a, r) + log.Println(s) } diff --git a/gone.in/square.png b/gone.to/square.png similarity index 100% rename from gone.in/square.png rename to gone.to/square.png diff --git a/link.go b/link.go deleted file mode 100644 index 1b76aa6..0000000 --- a/link.go +++ /dev/null @@ -1,189 +0,0 @@ -package gone - -import ( - "github.com/kpmy/ypk/assert" - "github.com/kpmy/ypk/halt" - "log" - "math" - "reflect" -) - -type Link struct { - i chan int - o chan int - owner string - id string - Weight int -} - -type Node struct { - Out []*Link - In []*Link - Obj interface{} -} - -var debug bool - -func init() { - debug = false -} - -func (l *Link) Write(c int) { - if debug { - log.Println("write", l.owner+":"+l.id, "<-", c) - } - l.i <- c - if debug { - log.Println("wrote", l.owner+":"+l.id, "<-", c) - } -} - -func (l *Link) Read() int { - if debug { - defer log.Println("ready", l.owner+":"+l.id) - log.Println("read", l.owner+":"+l.id) - } - return <-l.o -} - -func NewLink(owner, id string, weight int) (ret *Link) { - ret = &Link{owner: owner, id: id, Weight: weight} - ret.i = make(chan int) - ret.o = make(chan int) - go func(t *Link) { - x := <-t.i - for { - t.o <- x - } - }(ret) - return -} - -func Load(p *Perc) (ret map[string]*Node) { - this := func(owner string) (ret interface{}) { - switch owner[0] { - case 'a': - for _, x := range p.Ass { - if x.Id == owner { - return x - } - } - case 's': - for _, x := range p.Sens { - if x.Id == owner { - return x - } - } - default: - halt.As(100, owner) - } - return - } - var run func(_x interface{}, id string) *Link - run = func(_x interface{}, id string) *Link { - switch x := _x.(type) { - case *Ass: - cache := make(map[string]*Link) - if n, ok := ret[x.Id]; !ok { - next := new(Node) - for _, k := range x.In.Io { - next.In = append(next.In, run(this(k.Owner), k.Id)) - } - for _, o := range x.Out { - l := NewLink(x.Id, o.Id, o.Weight) - cache[o.Id] = l - next.Out = append(next.Out, l) - } - ret[x.Id] = next - next.Obj = x - go func(n *Node) { - for { - var buf []int - for _, k := range n.In { - buf = append(buf, k.Read()) - } - var sum int - for _, c := range buf { - sum += c - } - for _, k := range n.Out { - if sum > 1 { - k.Write(k.Weight) - } else { - k.Write(0) - } - } - } - }(next) - } else { - for _, o := range n.Out { - cache[o.id] = o - } - } - assert.For(len(cache) > 0, 60) - return cache[id] - case *Sens: - cache := make(map[string]*Link) - if n, ok := ret[x.Id]; !ok { - next := new(Node) - for _, o := range x.Out { - l := NewLink(x.Id, o.Id, o.Weight) - cache[o.Id] = l - next.Out = append(next.Out, l) - } - next.In = append(next.In, NewLink(x.Id, "0", 0)) - ret[x.Id] = next - next.Obj = x - go func(n *Node) { - x := n.In[0].Read() - for _, k := range n.Out { - if x == 1 { - k.Write(k.Weight) - } else { - k.Write(0) - } - } - }(next) - } else { - for _, o := range n.Out { - cache[o.id] = o - } - } - assert.For(len(cache) > 0, 60) - return cache[id] - default: - halt.As(100, reflect.TypeOf(x)) - } - panic(0) - } - ret = make(map[string]*Node) - for _, r := range p.React { - next := new(Node) - next.Out = append(next.Out, NewLink(r.Id, "0", 0)) - for _, k := range r.In.Io { - next.In = append(next.In, run(this(k.Owner), k.Id)) - } - next.Obj = r - ret[r.Id] = next - go func(n *Node) { - for { - var buf []int - for _, k := range n.In { - buf = append(buf, k.Read()) - } - var sum int - for _, c := range buf { - sum += c - } - for _, k := range n.Out { - if math.Signbit(float64(sum)) { - k.Write(1) - } else { - k.Write(-1) - } - } - } - }(next) - } - return -} diff --git a/model.go b/model.go deleted file mode 100644 index 9824d37..0000000 --- a/model.go +++ /dev/null @@ -1,38 +0,0 @@ -package gone - -type Out struct { - Owner string - Id string - Weight int -} - -func (o *Out) String() string { - return o.Owner + ":" + o.Id -} - -type In struct { - Io []*Out -} - -type Sens struct { - Id string - Out []*Out -} - -type Ass struct { - Id string - In *In - Out []*Out -} - -type React struct { - Id string - In *In - Out *Out -} - -type Perc struct { - Sens []*Sens - Ass []*Ass - React []*React -} diff --git a/perc/model.go b/perc/model.go index 1735a35..875d790 100644 --- a/perc/model.go +++ b/perc/model.go @@ -25,7 +25,7 @@ type Layer struct { } func (l *Layer) String() string { - return fmt.Sprint(l.Nodes) + return fmt.Sprint(l.Nodes, l.Next) } func NewNode() *Node { diff --git a/perc/std/sm.go b/perc/std/sm.go new file mode 100644 index 0000000..7594e6d --- /dev/null +++ b/perc/std/sm.go @@ -0,0 +1,56 @@ +package std + +import ( + "github.com/kpmy/ypk/assert" + "gone/perc" + "math/rand" +) + +func New(nn, no int, w_fn func() int) (ret *model.Layer) { + ret = &model.Layer{} + for i := 0; i < nn; i++ { + next := model.NewNode() + next.Out = make([]interface{}, rand.Intn(no)+1) + next.Weights = make([]int, len(next.Out)) + if w_fn != nil { + for i := 0; i < len(next.Weights); i++ { + next.Weights[i] = w_fn() + } + } + ret.Nodes = append(ret.Nodes, next) + } + return +} + +func Join(in *model.Layer, out *model.Layer) { + j := 0 + type im map[int]interface{} + cache := make([]im, len(out.Nodes)) + for k, n := range in.Nodes { + for i := 0; i < len(n.Out); { + assert.For(len(n.Out) <= len(out.Nodes), 20, len(n.Out), len(out.Nodes)) + l := model.Link{NodeId: k, LinkId: i} + skip := false + if cache[j] != nil { + if _, ok := cache[j][k]; ok { + skip = true + j++ + if j == len(cache) { + j = 0 + } + } + } + if !skip { + out.Nodes[j].In[l] = nil + if cache[j] == nil { + cache[j] = make(im) + } + cache[j][k] = l + //log.Println(l, "to", j) + i++ + } + //log.Println(k, len(n.Out), i, j) + } + } + in.Next = out +}