// Autocorrelation tests whether or not a generator produces independent results.
// The parameters are the dataset ds,
// start, the first index looked at by the test
// and jump, the ith index looked starting at (start)
func Autocorrelation(ds *RandGenerator.Dataset, start, jump int) (float64, float64) {

	// Index1 and Index2 keep tracks of when to break from the loop, as the array will be out of bounds when index2 is exceeds M
	var (
		index1 = start
		index2 = start + jump
		total  = 0.0

		k int
	)

	// Summation of each of the potentially correlated indices
	for k = 0; index2 < ds.Len(); k++ {
		total += ds.Get(index1) * ds.Get(index2)
		index1 = start + jump*k
		index2 = start + jump*(k+1)
	}

	// Now, take the total and divide it by the number of iterations + 1
	mu := total / float64((k + 1))

	mu -= 0.25 // Magic number provided by Professor Lipschultz in the slides

	// calculate the variance
	squaredVal := float64(13*k + 7)
	demoninator := float64(12 * (k + 1))
	variance := math.Sqrt(squaredVal) / demoninator
	return mu, variance
}
예제 #2
0
// The first option maps the difference between the value and the mean to a binary enum
func generateMeanRuns(ds *RandGenerator.Dataset) []bool {
	runs := make([]bool, ds.Len())

	mean := ds.Mean()

	for i := 0; int(i) < int(ds.Len()); i++ {
		point := ds.Get(i)
		runs[i] = math.Signbit(point - mean)
	}
	return runs
}
예제 #3
0
// The second method takes the difference between increasing indices and maps the sign of the difference to a binary result
func generateDifferenceRuns(ds *RandGenerator.Dataset) []bool {
	runs := make([]bool, ds.Len()-1)

	for i := 0; i < ds.Len()-1; i++ {
		point1 := ds.Get(i)
		point2 := ds.Get(i + 1)

		runs[i] = math.Signbit(point1 - point2)
	}
	return runs
}
func KolmogorovSmirnov(ds *RandGenerator.Dataset) float64 {
	ds = ds.Subset(0, 100).Sort() // only select the first 100 numbers, and sort them
	max := 0.0

	// Find the maximum difference from the expected value to the observed value
	for i := 0; i < ds.Len(); i++ {
		observed := ds.Get(i)
		expected := float64(i) / float64(ds.Len())

		distence := math.Abs(observed - expected)
		if distence > max {
			max = distence
		}
	}

	return max
}
예제 #5
0
func ChiSquared(ds *RandGenerator.Dataset) float64 {

	var buckets []int = make([]int, 10)
	for i := 0; i < 10; i++ {
		buckets[i] = 0
	}

	for i := 0; i < ds.Len(); i++ {
		num := ds.Get(i)
		switch {
		case num < 0.1:
			buckets[0] += 1
		case 0.1 <= num && num < 0.2:
			buckets[1] += 1
		case 0.2 <= num && num < 0.3:
			buckets[2] += 1
		case 0.3 <= num && num < 0.4:
			buckets[3] += 1
		case 0.4 <= num && num < 0.5:
			buckets[4] += 1
		case 0.5 <= num && num < 0.6:
			buckets[5] += 1
		case 0.6 <= num && num < 0.7:
			buckets[6] += 1
		case 0.7 <= num && num < 0.8:
			buckets[7] += 1
		case 0.8 <= num && num < 0.9:
			buckets[8] += 1
		case 0.9 <= num && num < 1.0:
			buckets[9] += 1

		default:
			log.Fatal("Generate produced a value greater than 1.0")
		}
	}

	testStatistic := 0.0
	for _, bucket := range buckets {
		var expected = ds.Len() / 10.0
		bucketVal := float64(bucket)
		testStatistic += ((bucketVal - float64(expected)) * (bucketVal - float64(expected))) / float64(expected)
	}
	return testStatistic
}
예제 #6
0
func main() {

	app := cli.NewApp()

	var (
		size       int
		outputFile string
		gen        RandGenerator.Generator
		ds         *RandGenerator.Dataset
	)

	const (
		SEED = 122949823
	)

	app.Flags = []cli.Flag{
		cli.IntFlag{
			Name:        "n",
			Value:       10000,
			Usage:       "number of elements to generate. Defaults to 10000. NOTE: Kolgorov only uses the first 100",
			Destination: &size,
		}, cli.StringFlag{
			Name:        "f",
			Value:       "output.txt",
			Usage:       "File to which the output is written, defaults to output.txt",
			Destination: &outputFile,
		},
	}

	// Specifies how to interact with the command line tool.
	// See https://github.com/codegangsta/cli for explanation
	app.Commands = []cli.Command{
		{
			Name:    "kolmogorov",
			Aliases: []string{"k"},
			Usage:   "run the Kolmogov-Smirnov Test for uniformity",
			Action: func(c *cli.Context) {
				println("Please specify a subcommand. See -h for a list of commands.")
				cli.ShowSubcommandHelp(c)
			},
			Subcommands: []cli.Command{
				{
					Name:  "stdlib",
					Usage: "uses the Golang standard library generator, found in 'golang.org/pkg/math/rand'",
					Action: func(c *cli.Context) {
						gen = rand.New(rand.NewSource(SEED))
						ds = RandGenerator.NewDataset(gen, size)
						fmt.Printf("Standard Library Kolmogorov Test Statistic:\t%f\n", StatTests.KolmogorovSmirnov(ds))
					},
				}, {
					Name:  "lipschultz",
					Usage: "uses the generator seeded as a = 101427, c = 321, m = 1 << 16",
					Action: func(c *cli.Context) {
						gen = RandGenerator.LipschultzGen()
						gen.Seed(SEED)
						ds = RandGenerator.NewDataset(gen, size)
						fmt.Printf("Lipschultz Kolmogorov Test Statistic:\t%f\n", StatTests.KolmogorovSmirnov(ds))
					},
				}, {
					Name:  "randu",
					Usage: "uses the generator seeded as a = 65539, c = 0, m = 1 << 31",
					Action: func(c *cli.Context) {
						gen = RandGenerator.NewRANDUGen()
						gen.Seed(SEED)
						ds = RandGenerator.NewDataset(gen, size)
						fmt.Printf("RANDU Kolmogorov Test Statistic:\t%f\n", StatTests.KolmogorovSmirnov(ds))
					},
				},
			},
		}, {
			Name:    "runs",
			Aliases: []string{"r"},
			Usage:   "runs Test for independence",
			Action: func(c *cli.Context) {
				cli.ShowSubcommandHelp(c)
			},
			Subcommands: []cli.Command{
				{
					Name:  "stdlib",
					Usage: "uses the Golang standard library generator, found in 'golang.org/pkg/math/rand'",
					Action: func(c *cli.Context) {
						gen = rand.New(rand.NewSource(SEED))
						ds = RandGenerator.NewDataset(gen, size)
						fmt.Printf("Standard Library Run Test Statistic:\t%f\n", StatTests.Run(ds, StatTests.DIFFERENCE))
					},
				}, {
					Name:  "lipschultz",
					Usage: "uses the generator seeded as a = 101427, c = 321, m = 1 << 16",
					Action: func(c *cli.Context) {
						gen = RandGenerator.LipschultzGen()
						gen.Seed(SEED)
						ds = RandGenerator.NewDataset(gen, size)
						fmt.Printf("Lipschultz Run Test Statistic:\t%f\n", StatTests.Run(ds, StatTests.DIFFERENCE))
					},
				}, {
					Name:  "randu",
					Usage: "uses the generator seeded as a = 65539, c = 0, m = 1 << 31",
					Action: func(c *cli.Context) {
						gen = RandGenerator.NewRANDUGen()
						gen.Seed(SEED)
						ds = RandGenerator.NewDataset(gen, size)
						fmt.Printf("RANDU Run Test Statistic:\t%f\n", StatTests.Run(ds, StatTests.DIFFERENCE))
					},
				},
			},
		}, {
			Name:    "autocorrelation",
			Aliases: []string{"a"},
			Usage:   "autocorrelation test for independence",
			Action: func(c *cli.Context) {
				cli.ShowSubcommandHelp(c)
				os.Exit(0)
			},
			Subcommands: []cli.Command{
				{
					Name:  "stdlib",
					Usage: "uses the Golang standard library generator, found in 'golang.org/pkg/math/rand'",
					Action: func(c *cli.Context) {
						gen = rand.New(rand.NewSource(SEED))
						ds = RandGenerator.NewDataset(gen, size)
						mu, variance := StatTests.Autocorrelation(ds, 1, 3)
						fmt.Printf("Standard Library Autocorrelation Test Statistic:\t%f\n", mu/variance)

					},
				}, {
					Name:  "lipschultz",
					Usage: "uses the generator seeded as a = 101427, c = 321, m = 1 << 16",
					Action: func(c *cli.Context) {
						gen = RandGenerator.LipschultzGen()
						gen.Seed(SEED)
						ds = RandGenerator.NewDataset(gen, size)
						mu, variance := StatTests.Autocorrelation(ds, 1, 3)
						fmt.Printf("Lipschultz Autocorrelation Test Statistic:\t%f\n", mu/variance)
					},
				}, {
					Name:  "randu",
					Usage: "uses the generator seeded as a = 65539, c = 0, m = 1 << 31",
					Action: func(c *cli.Context) {
						gen = RandGenerator.NewRANDUGen()
						gen.Seed(SEED)
						ds = RandGenerator.NewDataset(gen, size)
						mu, variance := StatTests.Autocorrelation(ds, 1, 3)
						fmt.Printf("RANDU Autocorrelation Test Statistic:\t%f\n", mu/variance)
					},
				},
			},
		}, {
			Name:    "chi",
			Aliases: []string{"c"},
			Usage:   "Chi-Square Frequency Test for uniformity",
			Action: func(c *cli.Context) {
				cli.ShowSubcommandHelp(c)
			},
			Subcommands: []cli.Command{
				{
					Name:  "stdlib",
					Usage: "uses the Golang standard library generator, found in 'golang.org/pkg/math/rand'",
					Action: func(c *cli.Context) {
						gen = rand.New(rand.NewSource(SEED))
						ds = RandGenerator.NewDataset(gen, size)
						fmt.Printf("Standard Library Chi Square Test Statistic:\t%f\n", StatTests.ChiSquared(ds))
					},
				}, {
					Name:  "lipschultz",
					Usage: "uses the generator seeded as a = 101427, c = 321, m = 1 << 16",
					Action: func(c *cli.Context) {
						gen = RandGenerator.LipschultzGen()
						gen.Seed(SEED)
						ds = RandGenerator.NewDataset(gen, size)
						fmt.Printf("Lipschultz Chi Square Test Statistic:\t%f\n", StatTests.ChiSquared(ds))
					},
				}, {
					Name:  "randu",
					Usage: "uses the generator seeded as a = 65539, c = 0, m = 1 << 31",
					Action: func(c *cli.Context) {
						gen = RandGenerator.NewRANDUGen()
						gen.Seed(SEED)
						ds = RandGenerator.NewDataset(gen, size)
						fmt.Printf("RANDU Chi Square Test Statistic:\t%f\n", StatTests.ChiSquared(ds))

					},
				},
			},
		},
	}

	app.Run(os.Args)

	file, err := os.Create(outputFile)
	if err != nil {
		panic(err)
	}

	// close file on exit and check for its returned error
	defer func() {
		if err := file.Close(); err != nil {
			panic(err)
		}
	}()

	w := bufio.NewWriter(file)
	defer w.Flush()

	for i := 0; i < ds.Len(); i++ {
		val := ds.Get(i)
		w.WriteString(fmt.Sprintf("%f\n", val))
	}
}