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 { panic("bad n in getn") }
    142 	req := make([] chan int, 2)
    143 	dat := make([] chan item, 2)
    144 	out := make([]item, 2)
    145 	var i int
    146 	var it item
    147 	for i=0; i<n; i++ {
    148 		req[i] = in[i].req
    149 		dat[i] = nil
    150 	}
    151 	for n=2*n; n>0; n-- {
    152 		seqno++
    153 
    154 		select{
    155 		case req[0] <- seqno:
    156 			dat[0] = in[0].dat
    157 			req[0] = nil
    158 		case req[1] <- seqno:
    159 			dat[1] = in[1].dat
    160 			req[1] = nil
    161 		case it = <-dat[0]:
    162 			out[0] = it
    163 			dat[0] = nil
    164 		case it = <-dat[1]:
    165 			out[1] = it
    166 			dat[1] = nil
    167 		}
    168 	}
    169 	return out
    170 }
    171 
    172 // Get one item from each of 2 demand channels
    173 
    174 func get2(in0 *dch, in1 *dch)  []item {
    175 	return getn([]*dch{in0, in1})
    176 }
    177 
    178 func copy(in *dch, out *dch){
    179 	for {
    180 		<-out.req
    181 		out.dat <- get(in)
    182 	}
    183 }
    184 
    185 func repeat(dat item, out *dch){
    186 	for {
    187 		put(dat, out)
    188 	}
    189 }
    190 
    191 type PS *dch	// power series
    192 type PS2 *[2] PS // pair of power series
    193 
    194 var Ones PS
    195 var Twos PS
    196 
    197 func mkPS() *dch {
    198 	return mkdch()
    199 }
    200 
    201 func mkPS2() *dch2 {
    202 	return mkdch2()
    203 }
    204 
    205 // Conventions
    206 // Upper-case for power series.
    207 // Lower-case for rationals.
    208 // Input variables: U,V,...
    209 // Output variables: ...,Y,Z
    210 
    211 // Integer gcd; needed for rational arithmetic
    212 
    213 func gcd (u, v int64) int64{
    214 	if u < 0 { return gcd(-u, v) }
    215 	if u == 0 { return v }
    216 	return gcd(v%u, u)
    217 }
    218 
    219 // Make a rational from two ints and from one int
    220 
    221 func i2tor(u, v int64) *rat{
    222 	g := gcd(u,v)
    223 	r := new(rat)
    224 	if v > 0 {
    225 		r.num = u/g
    226 		r.den = v/g
    227 	} else {
    228 		r.num = -u/g
    229 		r.den = -v/g
    230 	}
    231 	return r
    232 }
    233 
    234 func itor(u int64) *rat{
    235 	return i2tor(u, 1)
    236 }
    237 
    238 var zero *rat
    239 var one *rat
    240 
    241 
    242 // End mark and end test
    243 
    244 var finis *rat
    245 
    246 func end(u *rat) int64 {
    247 	if u.den==0 { return 1 }
    248 	return 0
    249 }
    250 
    251 // Operations on rationals
    252 
    253 func add(u, v *rat) *rat {
    254 	g := gcd(u.den,v.den)
    255 	return  i2tor(u.num*(v.den/g)+v.num*(u.den/g),u.den*(v.den/g))
    256 }
    257 
    258 func mul(u, v *rat) *rat{
    259 	g1 := gcd(u.num,v.den)
    260 	g2 := gcd(u.den,v.num)
    261 	r := new(rat)
    262 	r.num =(u.num/g1)*(v.num/g2)
    263 	r.den = (u.den/g2)*(v.den/g1)
    264 	return r
    265 }
    266 
    267 func neg(u *rat) *rat{
    268 	return i2tor(-u.num, u.den)
    269 }
    270 
    271 func sub(u, v *rat) *rat{
    272 	return add(u, neg(v))
    273 }
    274 
    275 func inv(u *rat) *rat{	// invert a rat
    276 	if u.num == 0 { panic("zero divide in inv") }
    277 	return i2tor(u.den, u.num)
    278 }
    279 
    280 // print eval in floating point of PS at x=c to n terms
    281 func Evaln(c *rat, U PS, n int) {
    282 	xn := float64(1)
    283 	x := float64(c.num)/float64(c.den)
    284 	val := float64(0)
    285 	for i:=0; i<n; i++ {
    286 		u := get(U)
    287 		if end(u) != 0 {
    288 			break
    289 		}
    290 		val = val + x * float64(u.num)/float64(u.den)
    291 		xn = xn*x
    292 	}
    293 	print(val, "\n")
    294 }
    295 
    296 // Print n terms of a power series
    297 func Printn(U PS, n int){
    298 	done := false
    299 	for ; !done && n>0; n-- {
    300 		u := get(U)
    301 		if end(u) != 0 {
    302 			done = true
    303 		} else {
    304 			u.pr()
    305 		}
    306 	}
    307 	print(("\n"))
    308 }
    309 
    310 func Print(U PS){
    311 	Printn(U,1000000000)
    312 }
    313 
    314 // Evaluate n terms of power series U at x=c
    315 func eval(c *rat, U PS, n int) *rat{
    316 	if n==0 { return zero }
    317 	y := get(U)
    318 	if end(y) != 0 { return zero }
    319 	return add(y,mul(c,eval(c,U,n-1)))
    320 }
    321 
    322 // Power-series constructors return channels on which power
    323 // series flow.  They start an encapsulated generator that
    324 // puts the terms of the series on the channel.
    325 
    326 // Make a pair of power series identical to a given power series
    327 
    328 func Split(U PS) *dch2{
    329 	UU := mkdch2()
    330 	go split(U,UU)
    331 	return UU
    332 }
    333 
    334 // Add two power series
    335 func Add(U, V PS) PS{
    336 	Z := mkPS()
    337 	go func(U, V, Z PS){
    338 		var uv [] item
    339 		for {
    340 			<-Z.req
    341 			uv = get2(U,V)
    342 			switch end(uv[0].(*rat))+2*end(uv[1].(*rat)) {
    343 			case 0:
    344 				Z.dat <- add(uv[0].(*rat), uv[1].(*rat))
    345 			case 1:
    346 				Z.dat <- uv[1]
    347 				copy(V,Z)
    348 			case 2:
    349 				Z.dat <- uv[0]
    350 				copy(U,Z)
    351 			case 3:
    352 				Z.dat <- finis
    353 			}
    354 		}
    355 	}(U, V, Z)
    356 	return Z
    357 }
    358 
    359 // Multiply a power series by a constant
    360 func Cmul(c *rat,U PS) PS{
    361 	Z := mkPS()
    362 	go func(c *rat, U, Z PS){
    363 		done := false
    364 		for !done {
    365 			<-Z.req
    366 			u := get(U)
    367 			if end(u) != 0 {
    368 				done = true
    369 			} else {
    370 				Z.dat <- mul(c,u)
    371 			}
    372 		}
    373 		Z.dat <- finis
    374 	}(c, U, Z)
    375 	return Z
    376 }
    377 
    378 // Subtract
    379 
    380 func Sub(U, V PS) PS{
    381 	return Add(U, Cmul(neg(one), V))
    382 }
    383 
    384 // Multiply a power series by the monomial x^n
    385 
    386 func Monmul(U PS, n int) PS{
    387 	Z := mkPS()
    388 	go func(n int, U PS, Z PS){
    389 		for ; n>0; n-- { put(zero,Z) }
    390 		copy(U,Z)
    391 	}(n, U, Z)
    392 	return Z
    393 }
    394 
    395 // Multiply by x
    396 
    397 func Xmul(U PS) PS{
    398 	return Monmul(U,1)
    399 }
    400 
    401 func Rep(c *rat) PS{
    402 	Z := mkPS()
    403 	go repeat(c,Z)
    404 	return Z
    405 }
    406 
    407 // Monomial c*x^n
    408 
    409 func Mon(c *rat, n int) PS{
    410 	Z:=mkPS()
    411 	go func(c *rat, n int, Z PS){
    412 		if(c.num!=0) {
    413 			for ; n>0; n=n-1 { put(zero,Z) }
    414 			put(c,Z)
    415 		}
    416 		put(finis,Z)
    417 	}(c, n, Z)
    418 	return Z
    419 }
    420 
    421 func Shift(c *rat, U PS) PS{
    422 	Z := mkPS()
    423 	go func(c *rat, U, Z PS){
    424 		put(c,Z)
    425 		copy(U,Z)
    426 	}(c, U, Z)
    427 	return Z
    428 }
    429 
    430 // simple pole at 1: 1/(1-x) = 1 1 1 1 1 ...
    431 
    432 // Convert array of coefficients, constant term first
    433 // to a (finite) power series
    434 
    435 /*
    436 func Poly(a [] *rat) PS{
    437 	Z:=mkPS()
    438 	begin func(a [] *rat, Z PS){
    439 		j:=0
    440 		done:=0
    441 		for j=len(a); !done&&j>0; j=j-1)
    442 			if(a[j-1].num!=0) done=1
    443 		i:=0
    444 		for(; i<j; i=i+1) put(a[i],Z)
    445 		put(finis,Z)
    446 	}()
    447 	return Z
    448 }
    449 */
    450 
    451 // Multiply. The algorithm is
    452 //	let U = u + x*UU
    453 //	let V = v + x*VV
    454 //	then UV = u*v + x*(u*VV+v*UU) + x*x*UU*VV
    455 
    456 func Mul(U, V PS) PS{
    457 	Z:=mkPS()
    458 	go func(U, V, Z PS){
    459 		<-Z.req
    460 		uv := get2(U,V)
    461 		if end(uv[0].(*rat))!=0 || end(uv[1].(*rat)) != 0 {
    462 			Z.dat <- finis
    463 		} else {
    464 			Z.dat <- mul(uv[0].(*rat),uv[1].(*rat))
    465 			UU := Split(U)
    466 			VV := Split(V)
    467 			W := Add(Cmul(uv[0].(*rat),VV[0]),Cmul(uv[1].(*rat),UU[0]))
    468 			<-Z.req
    469 			Z.dat <- get(W)
    470 			copy(Add(W,Mul(UU[1],VV[1])),Z)
    471 		}
    472 	}(U, V, Z)
    473 	return Z
    474 }
    475 
    476 // Differentiate
    477 
    478 func Diff(U PS) PS{
    479 	Z:=mkPS()
    480 	go func(U, Z PS){
    481 		<-Z.req
    482 		u := get(U)
    483 		if end(u) == 0 {
    484 			done:=false
    485 			for i:=1; !done; i++ {
    486 				u = get(U)
    487 				if end(u) != 0 {
    488 					done=true
    489 				} else {
    490 					Z.dat <- mul(itor(int64(i)),u)
    491 					<-Z.req
    492 				}
    493 			}
    494 		}
    495 		Z.dat <- finis
    496 	}(U, Z)
    497 	return Z
    498 }
    499 
    500 // Integrate, with const of integration
    501 func Integ(c *rat,U PS) PS{
    502 	Z:=mkPS()
    503 	go func(c *rat, U, Z PS){
    504 		put(c,Z)
    505 		done:=false
    506 		for i:=1; !done; i++ {
    507 			<-Z.req
    508 			u := get(U)
    509 			if end(u) != 0 { done= true }
    510 			Z.dat <- mul(i2tor(1,int64(i)),u)
    511 		}
    512 		Z.dat <- finis
    513 	}(c, U, Z)
    514 	return Z
    515 }
    516 
    517 // Binomial theorem (1+x)^c
    518 
    519 func Binom(c *rat) PS{
    520 	Z:=mkPS()
    521 	go func(c *rat, Z PS){
    522 		n := 1
    523 		t := itor(1)
    524 		for c.num!=0 {
    525 			put(t,Z)
    526 			t = mul(mul(t,c),i2tor(1,int64(n)))
    527 			c = sub(c,one)
    528 			n++
    529 		}
    530 		put(finis,Z)
    531 	}(c, Z)
    532 	return Z
    533 }
    534 
    535 // Reciprocal of a power series
    536 //	let U = u + x*UU
    537 //	let Z = z + x*ZZ
    538 //	(u+x*UU)*(z+x*ZZ) = 1
    539 //	z = 1/u
    540 //	u*ZZ + z*UU +x*UU*ZZ = 0
    541 //	ZZ = -UU*(z+x*ZZ)/u
    542 
    543 func Recip(U PS) PS{
    544 	Z:=mkPS()
    545 	go func(U, Z PS){
    546 		ZZ:=mkPS2()
    547 		<-Z.req
    548 		z := inv(get(U))
    549 		Z.dat <- z
    550 		split(Mul(Cmul(neg(z),U),Shift(z,ZZ[0])),ZZ)
    551 		copy(ZZ[1],Z)
    552 	}(U, Z)
    553 	return Z
    554 }
    555 
    556 // Exponential of a power series with constant term 0
    557 // (nonzero constant term would make nonrational coefficients)
    558 // bug: the constant term is simply ignored
    559 //	Z = exp(U)
    560 //	DZ = Z*DU
    561 //	integrate to get Z
    562 
    563 func Exp(U PS) PS{
    564 	ZZ := mkPS2()
    565 	split(Integ(one,Mul(ZZ[0],Diff(U))),ZZ)
    566 	return ZZ[1]
    567 }
    568 
    569 // Substitute V for x in U, where the leading term of V is zero
    570 //	let U = u + x*UU
    571 //	let V = v + x*VV
    572 //	then S(U,V) = u + VV*S(V,UU)
    573 // bug: a nonzero constant term is ignored
    574 
    575 func Subst(U, V PS) PS {
    576 	Z:= mkPS()
    577 	go func(U, V, Z PS) {
    578 		VV := Split(V)
    579 		<-Z.req
    580 		u := get(U)
    581 		Z.dat <- u
    582 		if end(u) == 0 {
    583 			if end(get(VV[0])) != 0 {
    584 				put(finis,Z)
    585 			} else {
    586 				copy(Mul(VV[0],Subst(U,VV[1])),Z)
    587 			}
    588 		}
    589 	}(U, V, Z)
    590 	return Z
    591 }
    592 
    593 // Monomial Substition: U(c x^n)
    594 // Each Ui is multiplied by c^i and followed by n-1 zeros
    595 
    596 func MonSubst(U PS, c0 *rat, n int) PS {
    597 	Z:= mkPS()
    598 	go func(U, Z PS, c0 *rat, n int) {
    599 		c := one
    600 		for {
    601 			<-Z.req
    602 			u := get(U)
    603 			Z.dat <- mul(u, c)
    604 			c = mul(c, c0)
    605 			if end(u) != 0 {
    606 				Z.dat <- finis
    607 				break
    608 			}
    609 			for i := 1; i < n; i++ {
    610 				<-Z.req
    611 				Z.dat <- zero
    612 			}
    613 		}
    614 	}(U, Z, c0, n)
    615 	return Z
    616 }
    617 
    618 
    619 func Init() {
    620 	chnameserial = -1
    621 	seqno = 0
    622 	chnames = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    623 	zero = itor(0)
    624 	one = itor(1)
    625 	finis = i2tor(1,0)
    626 	Ones = Rep(one)
    627 	Twos = Rep(itor(2))
    628 }
    629 
    630 func check(U PS, c *rat, count int, str string) {
    631 	for i := 0; i < count; i++ {
    632 		r := get(U)
    633 		if !r.eq(c) {
    634 			print("got: ")
    635 			r.pr()
    636 			print("should get ")
    637 			c.pr()
    638 			print("\n")
    639 			panic(str)
    640 		}
    641 	}
    642 }
    643 
    644 const N=10
    645 func checka(U PS, a []*rat, str string) {
    646 	for i := 0; i < N; i++ {
    647 		check(U, a[i], 1, str)
    648 	}
    649 }
    650 
    651 func main() {
    652 	Init()
    653 	if len(os.Args) > 1 {  // print
    654 		print("Ones: "); Printn(Ones, 10)
    655 		print("Twos: "); Printn(Twos, 10)
    656 		print("Add: "); Printn(Add(Ones, Twos), 10)
    657 		print("Diff: "); Printn(Diff(Ones), 10)
    658 		print("Integ: "); Printn(Integ(zero, Ones), 10)
    659 		print("CMul: "); Printn(Cmul(neg(one), Ones), 10)
    660 		print("Sub: "); Printn(Sub(Ones, Twos), 10)
    661 		print("Mul: "); Printn(Mul(Ones, Ones), 10)
    662 		print("Exp: "); Printn(Exp(Ones), 15)
    663 		print("MonSubst: "); Printn(MonSubst(Ones, neg(one), 2), 10)
    664 		print("ATan: "); Printn(Integ(zero, MonSubst(Ones, neg(one), 2)), 10)
    665 	} else {  // test
    666 		check(Ones, one, 5, "Ones")
    667 		check(Add(Ones, Ones), itor(2), 0, "Add Ones Ones")  // 1 1 1 1 1
    668 		check(Add(Ones, Twos), itor(3), 0, "Add Ones Twos") // 3 3 3 3 3
    669 		a := make([]*rat, N)
    670 		d := Diff(Ones)
    671 		for i:=0; i < N; i++ {
    672 			a[i] = itor(int64(i+1))
    673 		}
    674 		checka(d, a, "Diff")  // 1 2 3 4 5
    675 		in := Integ(zero, Ones)
    676 		a[0] = zero  // integration constant
    677 		for i:=1; i < N; i++ {
    678 			a[i] = i2tor(1, int64(i))
    679 		}
    680 		checka(in, a, "Integ")  // 0 1 1/2 1/3 1/4 1/5
    681 		check(Cmul(neg(one), Twos), itor(-2), 10, "CMul")  // -1 -1 -1 -1 -1
    682 		check(Sub(Ones, Twos), itor(-1), 0, "Sub Ones Twos")  // -1 -1 -1 -1 -1
    683 		m := Mul(Ones, Ones)
    684 		for i:=0; i < N; i++ {
    685 			a[i] = itor(int64(i+1))
    686 		}
    687 		checka(m, a, "Mul")  // 1 2 3 4 5
    688 		e := Exp(Ones)
    689 		a[0] = itor(1)
    690 		a[1] = itor(1)
    691 		a[2] = i2tor(3,2)
    692 		a[3] = i2tor(13,6)
    693 		a[4] = i2tor(73,24)
    694 		a[5] = i2tor(167,40)
    695 		a[6] = i2tor(4051,720)
    696 		a[7] = i2tor(37633,5040)
    697 		a[8] = i2tor(43817,4480)
    698 		a[9] = i2tor(4596553,362880)
    699 		checka(e, a, "Exp")  // 1 1 3/2 13/6 73/24
    700 		at := Integ(zero, MonSubst(Ones, neg(one), 2))
    701 		for c, i := 1, 0; i < N; i++ {
    702 			if i%2 == 0 {
    703 				a[i] = zero
    704 			} else {
    705 				a[i] = i2tor(int64(c), int64(i))
    706 				c *= -1
    707 			}
    708 		}
    709 		checka(at, a, "ATan");  // 0 -1 0 -1/3 0 -1/5
    710 /*
    711 		t := Revert(Integ(zero, MonSubst(Ones, neg(one), 2)))
    712 		a[0] = zero
    713 		a[1] = itor(1)
    714 		a[2] = zero
    715 		a[3] = i2tor(1,3)
    716 		a[4] = zero
    717 		a[5] = i2tor(2,15)
    718 		a[6] = zero
    719 		a[7] = i2tor(17,315)
    720 		a[8] = zero
    721 		a[9] = i2tor(62,2835)
    722 		checka(t, a, "Tan")  // 0 1 0 1/3 0 2/15
    723 */
    724 	}
    725 }
    726