File: noise.4th

package info (click to toggle)
kforth 20010227-2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 508 kB
  • ctags: 652
  • sloc: asm: 2,026; cpp: 1,795; ansic: 575; makefile: 64
file content (92 lines) | stat: -rw-r--r-- 1,953 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
\
\  noise.4th
\
\  Pseudo-random noise generation routines:
\
\	ran0	generates a random number between 0e and 1e with a
\		uniform distribution. Translated from Numerical Recipes
\		in C, by Press, et. al. 
\
\	gauss 	generates statistical noise with a normal distribution
\    		having mean of 0e and variance of 1e. Uses the output
\		of ran0 to generate a uniform deviate and
\ 		transforms this number into a normally distributed
\ 		deviate.
\
\ Notes:
\
\ 	The formula for the inverse cumulative distribution function (CDF)
\	of a normal distribution is taken from Abramowitz and Stegun, p. 933.
\

variable idum

16807 constant IA
2147483647 constant IM
1e IM s>f f/ fconstant AM
127773 constant IQ
2836 constant IR
123459876 constant MASK

\ The word ran0 returns an observation from a uniform distribution
\   between 0. and 1.
\
\   Initialize the variable idum to any integer value prior to calling
\   ran0. Do not alter idum between calls for successive deviates in
\   a sequence.

: ran0 ( -- f )
	idum @ MASK xor dup idum !
	IQ / 
	dup IR * swap
	IQ * idum @ swap - IA *
	swap - idum !
	idum @ 0< if
	  IM idum +!
	then
	idum @ s>f AM f*
	idum @ MASK xor idum !	
;

variable iflag

2.515517e fconstant C0
.802853e fconstant C1
.010328e fconstant C2
1.432788e fconstant D1
.189269e fconstant D2
.001308e fconstant D3

: gauss ( -- f | generate a pseudo-random number with a Gaussian distribution )

	false iflag !

	begin
	  ran0
	  fdup
	  f0=
	while
	  fdrop
	repeat

	fdup 0.5e f> dup iflag !
	if 1e fswap f- then			\ compute X

\ Compute the inverse of the CDF

	fdup f* 1e fswap f/ flog fsqrt		\ compute T		
	fdup 3e f** D3 f*
	fover fdup f* D2 f* f+
	fover D1 f* f+ 1e f+			\ compute 1+D1*T+D2*T^2+D3*T^3
	>r >r
	fdup fdup f* C2 f*
	fover C1 f* f+ C0 f+			\ compute C0+C1*T+C2*T^2
	r> r> 
	f/ f-
	iflag @ if fnegate then

\ T = SQRT(LOG(1./X**2.))
\ XP = T - (C0+C1*T+C2*T**2.)/(1.+D1*T+D2*T**2.+D3*T**3.)
\ IF (IFLAG) XP = -XP

;