]> Cypherpunks.ru repositories - gostls13.git/blob - test/chan/powser2.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / chan / powser2.go
1 // run
2
3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Test concurrency primitives: power series.
8
9 // Like powser1.go but uses channels of interfaces.
10 // Has not been cleaned up as much as powser1.go, to keep
11 // it distinct and therefore a different test.
12
13 // Power series package
14 // A power series is a channel, along which flow rational
15 // coefficients.  A denominator of zero signifies the end.
16 // Original code in Newsqueak by Doug McIlroy.
17 // See Squinting at Power Series by Doug McIlroy,
18 //   https://swtch.com/~rsc/thread/squint.pdf
19
20 package main
21
22 import "os"
23
24 type rat struct {
25         num, den int64 // numerator, denominator
26 }
27
28 type item interface {
29         pr()
30         eq(c item) bool
31 }
32
33 func (u *rat) pr() {
34         if u.den == 1 {
35                 print(u.num)
36         } else {
37                 print(u.num, "/", u.den)
38         }
39         print(" ")
40 }
41
42 func (u *rat) eq(c item) bool {
43         c1 := c.(*rat)
44         return u.num == c1.num && u.den == c1.den
45 }
46
47 type dch struct {
48         req chan int
49         dat chan item
50         nam int
51 }
52
53 type dch2 [2]*dch
54
55 var chnames string
56 var chnameserial int
57 var seqno int
58
59 func mkdch() *dch {
60         c := chnameserial % len(chnames)
61         chnameserial++
62         d := new(dch)
63         d.req = make(chan int)
64         d.dat = make(chan item)
65         d.nam = c
66         return d
67 }
68
69 func mkdch2() *dch2 {
70         d2 := new(dch2)
71         d2[0] = mkdch()
72         d2[1] = mkdch()
73         return d2
74 }
75
76 // split reads a single demand channel and replicates its
77 // output onto two, which may be read at different rates.
78 // A process is created at first demand for an item and dies
79 // after the item has been sent to both outputs.
80
81 // When multiple generations of split exist, the newest
82 // will service requests on one channel, which is
83 // always renamed to be out[0]; the oldest will service
84 // requests on the other channel, out[1].  All generations but the
85 // newest hold queued data that has already been sent to
86 // out[0].  When data has finally been sent to out[1],
87 // a signal on the release-wait channel tells the next newer
88 // generation to begin servicing out[1].
89
90 func dosplit(in *dch, out *dch2, wait chan int) {
91         both := false // do not service both channels
92
93         select {
94         case <-out[0].req:
95
96         case <-wait:
97                 both = true
98                 select {
99                 case <-out[0].req:
100
101                 case <-out[1].req:
102                         out[0], out[1] = out[1], out[0]
103                 }
104         }
105
106         seqno++
107         in.req <- seqno
108         release := make(chan int)
109         go dosplit(in, out, release)
110         dat := <-in.dat
111         out[0].dat <- dat
112         if !both {
113                 <-wait
114         }
115         <-out[1].req
116         out[1].dat <- dat
117         release <- 0
118 }
119
120 func split(in *dch, out *dch2) {
121         release := make(chan int)
122         go dosplit(in, out, release)
123         release <- 0
124 }
125
126 func put(dat item, out *dch) {
127         <-out.req
128         out.dat <- dat
129 }
130
131 func get(in *dch) *rat {
132         seqno++
133         in.req <- seqno
134         return (<-in.dat).(*rat)
135 }
136
137 // Get one item from each of n demand channels
138
139 func getn(in []*dch) []item {
140         n := len(in)
141         if n != 2 {
142                 panic("bad n in getn")
143         }
144         req := make([]chan int, 2)
145         dat := make([]chan item, 2)
146         out := make([]item, 2)
147         var i int
148         var it item
149         for i = 0; i < n; i++ {
150                 req[i] = in[i].req
151                 dat[i] = nil
152         }
153         for n = 2 * n; n > 0; n-- {
154                 seqno++
155
156                 select {
157                 case req[0] <- seqno:
158                         dat[0] = in[0].dat
159                         req[0] = nil
160                 case req[1] <- seqno:
161                         dat[1] = in[1].dat
162                         req[1] = nil
163                 case it = <-dat[0]:
164                         out[0] = it
165                         dat[0] = nil
166                 case it = <-dat[1]:
167                         out[1] = it
168                         dat[1] = nil
169                 }
170         }
171         return out
172 }
173
174 // Get one item from each of 2 demand channels
175
176 func get2(in0 *dch, in1 *dch) []item {
177         return getn([]*dch{in0, in1})
178 }
179
180 func copy(in *dch, out *dch) {
181         for {
182                 <-out.req
183                 out.dat <- get(in)
184         }
185 }
186
187 func repeat(dat item, out *dch) {
188         for {
189                 put(dat, out)
190         }
191 }
192
193 type PS *dch    // power series
194 type PS2 *[2]PS // pair of power series
195
196 var Ones PS
197 var Twos PS
198
199 func mkPS() *dch {
200         return mkdch()
201 }
202
203 func mkPS2() *dch2 {
204         return mkdch2()
205 }
206
207 // Conventions
208 // Upper-case for power series.
209 // Lower-case for rationals.
210 // Input variables: U,V,...
211 // Output variables: ...,Y,Z
212
213 // Integer gcd; needed for rational arithmetic
214
215 func gcd(u, v int64) int64 {
216         if u < 0 {
217                 return gcd(-u, v)
218         }
219         if u == 0 {
220                 return v
221         }
222         return gcd(v%u, u)
223 }
224
225 // Make a rational from two ints and from one int
226
227 func i2tor(u, v int64) *rat {
228         g := gcd(u, v)
229         r := new(rat)
230         if v > 0 {
231                 r.num = u / g
232                 r.den = v / g
233         } else {
234                 r.num = -u / g
235                 r.den = -v / g
236         }
237         return r
238 }
239
240 func itor(u int64) *rat {
241         return i2tor(u, 1)
242 }
243
244 var zero *rat
245 var one *rat
246
247 // End mark and end test
248
249 var finis *rat
250
251 func end(u *rat) int64 {
252         if u.den == 0 {
253                 return 1
254         }
255         return 0
256 }
257
258 // Operations on rationals
259
260 func add(u, v *rat) *rat {
261         g := gcd(u.den, v.den)
262         return i2tor(u.num*(v.den/g)+v.num*(u.den/g), u.den*(v.den/g))
263 }
264
265 func mul(u, v *rat) *rat {
266         g1 := gcd(u.num, v.den)
267         g2 := gcd(u.den, v.num)
268         r := new(rat)
269         r.num = (u.num / g1) * (v.num / g2)
270         r.den = (u.den / g2) * (v.den / g1)
271         return r
272 }
273
274 func neg(u *rat) *rat {
275         return i2tor(-u.num, u.den)
276 }
277
278 func sub(u, v *rat) *rat {
279         return add(u, neg(v))
280 }
281
282 func inv(u *rat) *rat { // invert a rat
283         if u.num == 0 {
284                 panic("zero divide in inv")
285         }
286         return i2tor(u.den, u.num)
287 }
288
289 // print eval in floating point of PS at x=c to n terms
290 func Evaln(c *rat, U PS, n int) {
291         xn := float64(1)
292         x := float64(c.num) / float64(c.den)
293         val := float64(0)
294         for i := 0; i < n; i++ {
295                 u := get(U)
296                 if end(u) != 0 {
297                         break
298                 }
299                 val = val + x*float64(u.num)/float64(u.den)
300                 xn = xn * x
301         }
302         print(val, "\n")
303 }
304
305 // Print n terms of a power series
306 func Printn(U PS, n int) {
307         done := false
308         for ; !done && n > 0; n-- {
309                 u := get(U)
310                 if end(u) != 0 {
311                         done = true
312                 } else {
313                         u.pr()
314                 }
315         }
316         print(("\n"))
317 }
318
319 func Print(U PS) {
320         Printn(U, 1000000000)
321 }
322
323 // Evaluate n terms of power series U at x=c
324 func eval(c *rat, U PS, n int) *rat {
325         if n == 0 {
326                 return zero
327         }
328         y := get(U)
329         if end(y) != 0 {
330                 return zero
331         }
332         return add(y, mul(c, eval(c, U, n-1)))
333 }
334
335 // Power-series constructors return channels on which power
336 // series flow.  They start an encapsulated generator that
337 // puts the terms of the series on the channel.
338
339 // Make a pair of power series identical to a given power series
340
341 func Split(U PS) *dch2 {
342         UU := mkdch2()
343         go split(U, UU)
344         return UU
345 }
346
347 // Add two power series
348 func Add(U, V PS) PS {
349         Z := mkPS()
350         go func(U, V, Z PS) {
351                 var uv []item
352                 for {
353                         <-Z.req
354                         uv = get2(U, V)
355                         switch end(uv[0].(*rat)) + 2*end(uv[1].(*rat)) {
356                         case 0:
357                                 Z.dat <- add(uv[0].(*rat), uv[1].(*rat))
358                         case 1:
359                                 Z.dat <- uv[1]
360                                 copy(V, Z)
361                         case 2:
362                                 Z.dat <- uv[0]
363                                 copy(U, Z)
364                         case 3:
365                                 Z.dat <- finis
366                         }
367                 }
368         }(U, V, Z)
369         return Z
370 }
371
372 // Multiply a power series by a constant
373 func Cmul(c *rat, U PS) PS {
374         Z := mkPS()
375         go func(c *rat, U, Z PS) {
376                 done := false
377                 for !done {
378                         <-Z.req
379                         u := get(U)
380                         if end(u) != 0 {
381                                 done = true
382                         } else {
383                                 Z.dat <- mul(c, u)
384                         }
385                 }
386                 Z.dat <- finis
387         }(c, U, Z)
388         return Z
389 }
390
391 // Subtract
392
393 func Sub(U, V PS) PS {
394         return Add(U, Cmul(neg(one), V))
395 }
396
397 // Multiply a power series by the monomial x^n
398
399 func Monmul(U PS, n int) PS {
400         Z := mkPS()
401         go func(n int, U PS, Z PS) {
402                 for ; n > 0; n-- {
403                         put(zero, Z)
404                 }
405                 copy(U, Z)
406         }(n, U, Z)
407         return Z
408 }
409
410 // Multiply by x
411
412 func Xmul(U PS) PS {
413         return Monmul(U, 1)
414 }
415
416 func Rep(c *rat) PS {
417         Z := mkPS()
418         go repeat(c, Z)
419         return Z
420 }
421
422 // Monomial c*x^n
423
424 func Mon(c *rat, n int) PS {
425         Z := mkPS()
426         go func(c *rat, n int, Z PS) {
427                 if c.num != 0 {
428                         for ; n > 0; n = n - 1 {
429                                 put(zero, Z)
430                         }
431                         put(c, Z)
432                 }
433                 put(finis, Z)
434         }(c, n, Z)
435         return Z
436 }
437
438 func Shift(c *rat, U PS) PS {
439         Z := mkPS()
440         go func(c *rat, U, Z PS) {
441                 put(c, Z)
442                 copy(U, Z)
443         }(c, U, Z)
444         return Z
445 }
446
447 // simple pole at 1: 1/(1-x) = 1 1 1 1 1 ...
448
449 // Convert array of coefficients, constant term first
450 // to a (finite) power series
451
452 /*
453 func Poly(a [] *rat) PS{
454         Z:=mkPS()
455         begin func(a [] *rat, Z PS){
456                 j:=0
457                 done:=0
458                 for j=len(a); !done&&j>0; j=j-1)
459                         if(a[j-1].num!=0) done=1
460                 i:=0
461                 for(; i<j; i=i+1) put(a[i],Z)
462                 put(finis,Z)
463         }()
464         return Z
465 }
466 */
467
468 // Multiply. The algorithm is
469 //      let U = u + x*UU
470 //      let V = v + x*VV
471 //      then UV = u*v + x*(u*VV+v*UU) + x*x*UU*VV
472
473 func Mul(U, V PS) PS {
474         Z := mkPS()
475         go func(U, V, Z PS) {
476                 <-Z.req
477                 uv := get2(U, V)
478                 if end(uv[0].(*rat)) != 0 || end(uv[1].(*rat)) != 0 {
479                         Z.dat <- finis
480                 } else {
481                         Z.dat <- mul(uv[0].(*rat), uv[1].(*rat))
482                         UU := Split(U)
483                         VV := Split(V)
484                         W := Add(Cmul(uv[0].(*rat), VV[0]), Cmul(uv[1].(*rat), UU[0]))
485                         <-Z.req
486                         Z.dat <- get(W)
487                         copy(Add(W, Mul(UU[1], VV[1])), Z)
488                 }
489         }(U, V, Z)
490         return Z
491 }
492
493 // Differentiate
494
495 func Diff(U PS) PS {
496         Z := mkPS()
497         go func(U, Z PS) {
498                 <-Z.req
499                 u := get(U)
500                 if end(u) == 0 {
501                         done := false
502                         for i := 1; !done; i++ {
503                                 u = get(U)
504                                 if end(u) != 0 {
505                                         done = true
506                                 } else {
507                                         Z.dat <- mul(itor(int64(i)), u)
508                                         <-Z.req
509                                 }
510                         }
511                 }
512                 Z.dat <- finis
513         }(U, Z)
514         return Z
515 }
516
517 // Integrate, with const of integration
518 func Integ(c *rat, U PS) PS {
519         Z := mkPS()
520         go func(c *rat, U, Z PS) {
521                 put(c, Z)
522                 done := false
523                 for i := 1; !done; i++ {
524                         <-Z.req
525                         u := get(U)
526                         if end(u) != 0 {
527                                 done = true
528                         }
529                         Z.dat <- mul(i2tor(1, int64(i)), u)
530                 }
531                 Z.dat <- finis
532         }(c, U, Z)
533         return Z
534 }
535
536 // Binomial theorem (1+x)^c
537
538 func Binom(c *rat) PS {
539         Z := mkPS()
540         go func(c *rat, Z PS) {
541                 n := 1
542                 t := itor(1)
543                 for c.num != 0 {
544                         put(t, Z)
545                         t = mul(mul(t, c), i2tor(1, int64(n)))
546                         c = sub(c, one)
547                         n++
548                 }
549                 put(finis, Z)
550         }(c, Z)
551         return Z
552 }
553
554 // Reciprocal of a power series
555 //      let U = u + x*UU
556 //      let Z = z + x*ZZ
557 //      (u+x*UU)*(z+x*ZZ) = 1
558 //      z = 1/u
559 //      u*ZZ + z*UU +x*UU*ZZ = 0
560 //      ZZ = -UU*(z+x*ZZ)/u
561
562 func Recip(U PS) PS {
563         Z := mkPS()
564         go func(U, Z PS) {
565                 ZZ := mkPS2()
566                 <-Z.req
567                 z := inv(get(U))
568                 Z.dat <- z
569                 split(Mul(Cmul(neg(z), U), Shift(z, ZZ[0])), ZZ)
570                 copy(ZZ[1], Z)
571         }(U, Z)
572         return Z
573 }
574
575 // Exponential of a power series with constant term 0
576 // (nonzero constant term would make nonrational coefficients)
577 // bug: the constant term is simply ignored
578 //      Z = exp(U)
579 //      DZ = Z*DU
580 //      integrate to get Z
581
582 func Exp(U PS) PS {
583         ZZ := mkPS2()
584         split(Integ(one, Mul(ZZ[0], Diff(U))), ZZ)
585         return ZZ[1]
586 }
587
588 // Substitute V for x in U, where the leading term of V is zero
589 //      let U = u + x*UU
590 //      let V = v + x*VV
591 //      then S(U,V) = u + VV*S(V,UU)
592 // bug: a nonzero constant term is ignored
593
594 func Subst(U, V PS) PS {
595         Z := mkPS()
596         go func(U, V, Z PS) {
597                 VV := Split(V)
598                 <-Z.req
599                 u := get(U)
600                 Z.dat <- u
601                 if end(u) == 0 {
602                         if end(get(VV[0])) != 0 {
603                                 put(finis, Z)
604                         } else {
605                                 copy(Mul(VV[0], Subst(U, VV[1])), Z)
606                         }
607                 }
608         }(U, V, Z)
609         return Z
610 }
611
612 // Monomial Substitution: U(c x^n)
613 // Each Ui is multiplied by c^i and followed by n-1 zeros
614
615 func MonSubst(U PS, c0 *rat, n int) PS {
616         Z := mkPS()
617         go func(U, Z PS, c0 *rat, n int) {
618                 c := one
619                 for {
620                         <-Z.req
621                         u := get(U)
622                         Z.dat <- mul(u, c)
623                         c = mul(c, c0)
624                         if end(u) != 0 {
625                                 Z.dat <- finis
626                                 break
627                         }
628                         for i := 1; i < n; i++ {
629                                 <-Z.req
630                                 Z.dat <- zero
631                         }
632                 }
633         }(U, Z, c0, n)
634         return Z
635 }
636
637 func Init() {
638         chnameserial = -1
639         seqno = 0
640         chnames = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
641         zero = itor(0)
642         one = itor(1)
643         finis = i2tor(1, 0)
644         Ones = Rep(one)
645         Twos = Rep(itor(2))
646 }
647
648 func check(U PS, c *rat, count int, str string) {
649         for i := 0; i < count; i++ {
650                 r := get(U)
651                 if !r.eq(c) {
652                         print("got: ")
653                         r.pr()
654                         print("should get ")
655                         c.pr()
656                         print("\n")
657                         panic(str)
658                 }
659         }
660 }
661
662 const N = 10
663
664 func checka(U PS, a []*rat, str string) {
665         for i := 0; i < N; i++ {
666                 check(U, a[i], 1, str)
667         }
668 }
669
670 func main() {
671         Init()
672         if len(os.Args) > 1 { // print
673                 print("Ones: ")
674                 Printn(Ones, 10)
675                 print("Twos: ")
676                 Printn(Twos, 10)
677                 print("Add: ")
678                 Printn(Add(Ones, Twos), 10)
679                 print("Diff: ")
680                 Printn(Diff(Ones), 10)
681                 print("Integ: ")
682                 Printn(Integ(zero, Ones), 10)
683                 print("CMul: ")
684                 Printn(Cmul(neg(one), Ones), 10)
685                 print("Sub: ")
686                 Printn(Sub(Ones, Twos), 10)
687                 print("Mul: ")
688                 Printn(Mul(Ones, Ones), 10)
689                 print("Exp: ")
690                 Printn(Exp(Ones), 15)
691                 print("MonSubst: ")
692                 Printn(MonSubst(Ones, neg(one), 2), 10)
693                 print("ATan: ")
694                 Printn(Integ(zero, MonSubst(Ones, neg(one), 2)), 10)
695         } else { // test
696                 check(Ones, one, 5, "Ones")
697                 check(Add(Ones, Ones), itor(2), 0, "Add Ones Ones") // 1 1 1 1 1
698                 check(Add(Ones, Twos), itor(3), 0, "Add Ones Twos") // 3 3 3 3 3
699                 a := make([]*rat, N)
700                 d := Diff(Ones)
701                 for i := 0; i < N; i++ {
702                         a[i] = itor(int64(i + 1))
703                 }
704                 checka(d, a, "Diff") // 1 2 3 4 5
705                 in := Integ(zero, Ones)
706                 a[0] = zero // integration constant
707                 for i := 1; i < N; i++ {
708                         a[i] = i2tor(1, int64(i))
709                 }
710                 checka(in, a, "Integ")                               // 0 1 1/2 1/3 1/4 1/5
711                 check(Cmul(neg(one), Twos), itor(-2), 10, "CMul")    // -1 -1 -1 -1 -1
712                 check(Sub(Ones, Twos), itor(-1), 0, "Sub Ones Twos") // -1 -1 -1 -1 -1
713                 m := Mul(Ones, Ones)
714                 for i := 0; i < N; i++ {
715                         a[i] = itor(int64(i + 1))
716                 }
717                 checka(m, a, "Mul") // 1 2 3 4 5
718                 e := Exp(Ones)
719                 a[0] = itor(1)
720                 a[1] = itor(1)
721                 a[2] = i2tor(3, 2)
722                 a[3] = i2tor(13, 6)
723                 a[4] = i2tor(73, 24)
724                 a[5] = i2tor(167, 40)
725                 a[6] = i2tor(4051, 720)
726                 a[7] = i2tor(37633, 5040)
727                 a[8] = i2tor(43817, 4480)
728                 a[9] = i2tor(4596553, 362880)
729                 checka(e, a, "Exp") // 1 1 3/2 13/6 73/24
730                 at := Integ(zero, MonSubst(Ones, neg(one), 2))
731                 for c, i := 1, 0; i < N; i++ {
732                         if i%2 == 0 {
733                                 a[i] = zero
734                         } else {
735                                 a[i] = i2tor(int64(c), int64(i))
736                                 c *= -1
737                         }
738                 }
739                 checka(at, a, "ATan") // 0 -1 0 -1/3 0 -1/5
740                 /*
741                         t := Revert(Integ(zero, MonSubst(Ones, neg(one), 2)))
742                         a[0] = zero
743                         a[1] = itor(1)
744                         a[2] = zero
745                         a[3] = i2tor(1,3)
746                         a[4] = zero
747                         a[5] = i2tor(2,15)
748                         a[6] = zero
749                         a[7] = i2tor(17,315)
750                         a[8] = zero
751                         a[9] = i2tor(62,2835)
752                         checka(t, a, "Tan")  // 0 1 0 1/3 0 2/15
753                 */
754         }
755 }