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.
7 // Test concurrency primitives: power series.
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.
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
25 num, den int64 // numerator, denominator
37 print(u.num, "/", u.den)
42 func (u *rat) eq(c item) bool {
44 return u.num == c1.num && u.den == c1.den
60 c := chnameserial % len(chnames)
63 d.req = make(chan int)
64 d.dat = make(chan item)
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.
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].
90 func dosplit(in *dch, out *dch2, wait chan int) {
91 both := false // do not service both channels
102 out[0], out[1] = out[1], out[0]
108 release := make(chan int)
109 go dosplit(in, out, release)
120 func split(in *dch, out *dch2) {
121 release := make(chan int)
122 go dosplit(in, out, release)
126 func put(dat item, out *dch) {
131 func get(in *dch) *rat {
134 return (<-in.dat).(*rat)
137 // Get one item from each of n demand channels
139 func getn(in []*dch) []item {
142 panic("bad n in getn")
144 req := make([]chan int, 2)
145 dat := make([]chan item, 2)
146 out := make([]item, 2)
149 for i = 0; i < n; i++ {
153 for n = 2 * n; n > 0; n-- {
157 case req[0] <- seqno:
160 case req[1] <- seqno:
174 // Get one item from each of 2 demand channels
176 func get2(in0 *dch, in1 *dch) []item {
177 return getn([]*dch{in0, in1})
180 func copy(in *dch, out *dch) {
187 func repeat(dat item, out *dch) {
193 type PS *dch // power series
194 type PS2 *[2]PS // pair of power series
208 // Upper-case for power series.
209 // Lower-case for rationals.
210 // Input variables: U,V,...
211 // Output variables: ...,Y,Z
213 // Integer gcd; needed for rational arithmetic
215 func gcd(u, v int64) int64 {
225 // Make a rational from two ints and from one int
227 func i2tor(u, v int64) *rat {
240 func itor(u int64) *rat {
247 // End mark and end test
251 func end(u *rat) int64 {
258 // Operations on rationals
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))
265 func mul(u, v *rat) *rat {
266 g1 := gcd(u.num, v.den)
267 g2 := gcd(u.den, v.num)
269 r.num = (u.num / g1) * (v.num / g2)
270 r.den = (u.den / g2) * (v.den / g1)
274 func neg(u *rat) *rat {
275 return i2tor(-u.num, u.den)
278 func sub(u, v *rat) *rat {
279 return add(u, neg(v))
282 func inv(u *rat) *rat { // invert a rat
284 panic("zero divide in inv")
286 return i2tor(u.den, u.num)
289 // print eval in floating point of PS at x=c to n terms
290 func Evaln(c *rat, U PS, n int) {
292 x := float64(c.num) / float64(c.den)
294 for i := 0; i < n; i++ {
299 val = val + x*float64(u.num)/float64(u.den)
305 // Print n terms of a power series
306 func Printn(U PS, n int) {
308 for ; !done && n > 0; n-- {
320 Printn(U, 1000000000)
323 // Evaluate n terms of power series U at x=c
324 func eval(c *rat, U PS, n int) *rat {
332 return add(y, mul(c, eval(c, U, n-1)))
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.
339 // Make a pair of power series identical to a given power series
341 func Split(U PS) *dch2 {
347 // Add two power series
348 func Add(U, V PS) PS {
350 go func(U, V, Z PS) {
355 switch end(uv[0].(*rat)) + 2*end(uv[1].(*rat)) {
357 Z.dat <- add(uv[0].(*rat), uv[1].(*rat))
372 // Multiply a power series by a constant
373 func Cmul(c *rat, U PS) PS {
375 go func(c *rat, U, Z PS) {
393 func Sub(U, V PS) PS {
394 return Add(U, Cmul(neg(one), V))
397 // Multiply a power series by the monomial x^n
399 func Monmul(U PS, n int) PS {
401 go func(n int, U PS, Z PS) {
416 func Rep(c *rat) PS {
424 func Mon(c *rat, n int) PS {
426 go func(c *rat, n int, Z PS) {
428 for ; n > 0; n = n - 1 {
438 func Shift(c *rat, U PS) PS {
440 go func(c *rat, U, Z PS) {
447 // simple pole at 1: 1/(1-x) = 1 1 1 1 1 ...
449 // Convert array of coefficients, constant term first
450 // to a (finite) power series
453 func Poly(a [] *rat) PS{
455 begin func(a [] *rat, Z PS){
458 for j=len(a); !done&&j>0; j=j-1)
459 if(a[j-1].num!=0) done=1
461 for(; i<j; i=i+1) put(a[i],Z)
468 // Multiply. The algorithm is
471 // then UV = u*v + x*(u*VV+v*UU) + x*x*UU*VV
473 func Mul(U, V PS) PS {
475 go func(U, V, Z PS) {
478 if end(uv[0].(*rat)) != 0 || end(uv[1].(*rat)) != 0 {
481 Z.dat <- mul(uv[0].(*rat), uv[1].(*rat))
484 W := Add(Cmul(uv[0].(*rat), VV[0]), Cmul(uv[1].(*rat), UU[0]))
487 copy(Add(W, Mul(UU[1], VV[1])), Z)
502 for i := 1; !done; i++ {
507 Z.dat <- mul(itor(int64(i)), u)
517 // Integrate, with const of integration
518 func Integ(c *rat, U PS) PS {
520 go func(c *rat, U, Z PS) {
523 for i := 1; !done; i++ {
529 Z.dat <- mul(i2tor(1, int64(i)), u)
536 // Binomial theorem (1+x)^c
538 func Binom(c *rat) PS {
540 go func(c *rat, Z PS) {
545 t = mul(mul(t, c), i2tor(1, int64(n)))
554 // Reciprocal of a power series
557 // (u+x*UU)*(z+x*ZZ) = 1
559 // u*ZZ + z*UU +x*UU*ZZ = 0
560 // ZZ = -UU*(z+x*ZZ)/u
562 func Recip(U PS) PS {
569 split(Mul(Cmul(neg(z), U), Shift(z, ZZ[0])), ZZ)
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
580 // integrate to get Z
584 split(Integ(one, Mul(ZZ[0], Diff(U))), ZZ)
588 // Substitute V for x in U, where the leading term of V is zero
591 // then S(U,V) = u + VV*S(V,UU)
592 // bug: a nonzero constant term is ignored
594 func Subst(U, V PS) PS {
596 go func(U, V, Z PS) {
602 if end(get(VV[0])) != 0 {
605 copy(Mul(VV[0], Subst(U, VV[1])), Z)
612 // Monomial Substitution: U(c x^n)
613 // Each Ui is multiplied by c^i and followed by n-1 zeros
615 func MonSubst(U PS, c0 *rat, n int) PS {
617 go func(U, Z PS, c0 *rat, n int) {
628 for i := 1; i < n; i++ {
640 chnames = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
648 func check(U PS, c *rat, count int, str string) {
649 for i := 0; i < count; i++ {
664 func checka(U PS, a []*rat, str string) {
665 for i := 0; i < N; i++ {
666 check(U, a[i], 1, str)
672 if len(os.Args) > 1 { // print
678 Printn(Add(Ones, Twos), 10)
680 Printn(Diff(Ones), 10)
682 Printn(Integ(zero, Ones), 10)
684 Printn(Cmul(neg(one), Ones), 10)
686 Printn(Sub(Ones, Twos), 10)
688 Printn(Mul(Ones, Ones), 10)
690 Printn(Exp(Ones), 15)
692 Printn(MonSubst(Ones, neg(one), 2), 10)
694 Printn(Integ(zero, MonSubst(Ones, neg(one), 2)), 10)
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
701 for i := 0; i < N; i++ {
702 a[i] = itor(int64(i + 1))
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))
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
714 for i := 0; i < N; i++ {
715 a[i] = itor(int64(i + 1))
717 checka(m, a, "Mul") // 1 2 3 4 5
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++ {
735 a[i] = i2tor(int64(c), int64(i))
739 checka(at, a, "ATan") // 0 -1 0 -1/3 0 -1/5
741 t := Revert(Integ(zero, MonSubst(Ones, neg(one), 2)))
751 a[9] = i2tor(62,2835)
752 checka(t, a, "Tan") // 0 1 0 1/3 0 2/15