Home | History | Annotate | Download | only in chan
      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 //   http://www.cs.bell-labs.com/who/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 Substition: 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 }
    756