Created
November 24, 2012 11:57
-
-
Save mitya57/4139353 to your computer and use it in GitHub Desktop.
Лабораторная №1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cmath> | |
#include <cstdlib> | |
#include <iostream> | |
#ifndef RANGE | |
#define RANGE 10000 | |
#endif | |
#ifndef CORRELATION_OFFSET | |
#define CORRELATION_OFFSET 10 | |
#endif | |
#define MIN(x, y) (x < y ? x : y) | |
#define MAX(x, y) (x > y ? x : y) | |
typedef unsigned int uint; | |
class AbstractSequence { | |
public: | |
uint startelement; | |
uint range; | |
virtual uint getNext(uint element) = 0; | |
}; | |
class Sequence1: public AbstractSequence { | |
public: | |
Sequence1() { | |
startelement = 1; | |
range = 16284; | |
} | |
virtual uint getNext(uint element) { | |
return (12 * element + 1) % 16284; | |
} | |
}; | |
class Sequence2: public AbstractSequence { | |
public: | |
Sequence2() { | |
startelement = 65535; | |
range = 65536; | |
} | |
virtual uint getNext(uint element) { | |
return (25173 * element + 13949) & 65535; | |
} | |
}; | |
class Sequence3: public AbstractSequence { | |
private: | |
uint n; | |
double s2; | |
public: | |
Sequence3() { | |
n = 1; | |
s2 = sqrt(2); | |
startelement = (s2-1) * RANGE; | |
range = RANGE; | |
} | |
virtual uint getNext(uint element) { | |
++n; | |
uint result = uint(n*s2*RANGE) % RANGE; | |
return (result > 0) ? result : startelement; | |
} | |
}; | |
class Sequence4: public AbstractSequence { | |
public: | |
Sequence4() { | |
startelement = rand() % RANGE; | |
range = RANGE; | |
} | |
virtual uint getNext(uint element) { | |
return rand() % RANGE; | |
} | |
}; | |
uint getPeriod(AbstractSequence *seq) { | |
uint element = seq->getNext(seq->startelement); | |
uint c = 1; | |
while (element != seq->startelement) { | |
if (element == seq->getNext(element)) | |
//return 0; | |
return c; | |
element = seq->getNext(element); | |
++c; | |
} | |
return c; | |
} | |
double getMeanValue(AbstractSequence *seq) { | |
uint sum = 0, period = getPeriod(seq); | |
uint element = seq->startelement; | |
for (uint i = 0; i < period; ++i) { | |
sum += element; | |
element = seq->getNext(element); | |
} | |
return (double(sum) / period) / seq->range; | |
} | |
double getDispersion(AbstractSequence *seq) { | |
uint sum = 0, period = getPeriod(seq); | |
uint element = seq->startelement; | |
double meanValue = getMeanValue(seq); | |
for (uint i = 0; i < period; ++i) { | |
sum += pow(element - meanValue, 2); | |
element = seq->getNext(element); | |
} | |
return (double(sum) / period) / seq->range; | |
} | |
double getCorrelation(AbstractSequence *seq) { | |
uint element1 = seq->startelement; | |
uint element2 = element1; | |
uint i; | |
double sum = 0; | |
for (i = 0; i < CORRELATION_OFFSET; ++i) | |
element2 = seq->getNext(element2); | |
uint period = getPeriod(seq); | |
double mv = getMeanValue(seq); | |
for (i = 0; i < period; ++i) { | |
sum += ((double(element1)/seq->range)-mv)*((double(element2)/seq->range)-mv); | |
element1 = seq->getNext(element1); | |
element2 = seq->getNext(element2); | |
} | |
double cov = sum / period; | |
return cov / getDispersion(seq); | |
} | |
double getPi(AbstractSequence *seq) { | |
uint circ = 0, period = getPeriod(seq), i; | |
uint element = seq->startelement, next; | |
for (i = 0; i < period; ++i) { | |
next = seq->getNext(element); | |
if (sqrt(pow(double(element)/seq->range - .5, 2) + pow(double(next)/seq->range - .5, 2)) < .5) | |
++circ; | |
element = seq->getNext(element); | |
} | |
return 4 * double(circ) / period; | |
} | |
void printPeriod(uint number, uint period) { | |
if (period) | |
std::cout << "Period of sequence " << number << " is " << period; | |
else | |
std::cout << "Sequence " << number << " has a fixed point"; | |
std::cout << std::endl; | |
} | |
double getChi2(AbstractSequence *seq, uint n) { | |
uint *counter = new uint[n]; | |
uint element = seq->getNext(seq->startelement); | |
uint c = 1, interval; | |
for (interval = 0; interval < n; ++interval) | |
counter[interval] = 0; | |
while (element != seq->startelement) { | |
interval = 0; | |
while (interval * seq->range > element * n | |
|| element * n >= (interval+1) * seq->range) | |
++interval; | |
++counter[interval]; | |
if (element == seq->getNext(element)) | |
break; | |
element = seq->getNext(element); | |
++c; | |
} | |
double chi2 = 0; | |
//std::cout << "counter is:"; | |
for (interval = 0; interval < n; ++interval) { | |
//std::cout << " " << counter[interval]; | |
chi2 += pow(double(counter[interval]) / c - 1, 2); | |
} | |
//std::cout << std::endl; | |
delete[] counter; | |
return chi2 / n; | |
} | |
int main(void) { | |
Sequence1 seq1; | |
Sequence2 seq2; | |
Sequence3 seq3; | |
Sequence4 seq4; | |
printPeriod(1, getPeriod(&seq1)); | |
printPeriod(2, getPeriod(&seq2)); | |
printPeriod(3, getPeriod(&seq3)); | |
printPeriod(4, getPeriod(&seq4)); | |
std::cout << "Mean value for sequence 1 is " << getMeanValue(&seq1) << std::endl; | |
std::cout << "Mean value for sequence 2 is " << getMeanValue(&seq2) << std::endl; | |
std::cout << "Mean value for sequence 3 is " << getMeanValue(&seq3) << std::endl; | |
std::cout << "Mean value for sequence 4 is " << getMeanValue(&seq4) << std::endl; | |
std::cout << "Pi for sequence 1 is " << getPi(&seq1) << std::endl; | |
std::cout << "Pi for sequence 2 is " << getPi(&seq2) << std::endl; | |
std::cout << "Pi for sequence 3 is " << getPi(&seq3) << std::endl; | |
std::cout << "Pi for sequence 4 is " << getPi(&seq4) << std::endl; | |
std::cout << "Correlation for sequence 1 is " << getCorrelation(&seq1) << std::endl; | |
std::cout << "Correlation for sequence 2 is " << getCorrelation(&seq2) << std::endl; | |
std::cout << "Correlation for sequence 3 is " << getCorrelation(&seq3) << std::endl; | |
std::cout << "Correlation for sequence 4 is " << getCorrelation(&seq4) << std::endl; | |
std::cout << "Chi^2 for sequence 1 is " << getChi2(&seq1, 10) << std::endl; | |
std::cout << "Chi^2 for sequence 2 is " << getChi2(&seq2, 10) << std::endl; | |
std::cout << "Chi^2 for sequence 3 is " << getChi2(&seq3, 10) << std::endl; | |
std::cout << "Chi^2 for sequence 4 is " << getChi2(&seq4, 10) << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment