79 lines
2.4 KiB
C++
79 lines
2.4 KiB
C++
|
#include <cstdlib>
|
||
|
#include <iomanip>
|
||
|
#include <iostream>
|
||
|
|
||
|
#include "chain-random-walk.h"
|
||
|
|
||
|
using namespace crw;
|
||
|
|
||
|
namespace {
|
||
|
// set each element forward or backward by 1, at random
|
||
|
void stochastic_unit_step(long size, float config[])
|
||
|
{
|
||
|
for(long i = 0; i < size; i++)
|
||
|
if(std::rand() % 2 == 0) config[i]++;
|
||
|
else config[i]--;
|
||
|
}
|
||
|
|
||
|
void shift_centre_to_origin(long size, float config[])
|
||
|
{
|
||
|
double sum = 0.0;
|
||
|
for(long i = 0; i < size; i++) sum += config[i];
|
||
|
for(long i = 0; i < size; i++) config[i] -= sum/size;
|
||
|
}
|
||
|
|
||
|
const int el_out_max = 9; // show at most the first nine elements
|
||
|
}
|
||
|
|
||
|
float crw::elongation(long size, float config[])
|
||
|
{
|
||
|
float min = config[0];
|
||
|
float max = config[0];
|
||
|
|
||
|
for(long i = 1; i < size; i++)
|
||
|
if(config[i] > max) max = config[i];
|
||
|
else if(config[i] < min) min = config[i];
|
||
|
|
||
|
return max - min;
|
||
|
}
|
||
|
|
||
|
float* crw::step(long size, float previous[])
|
||
|
{
|
||
|
// allocate the next configuration
|
||
|
float* config = new float[size]();
|
||
|
|
||
|
// first, let the chain contract: each element is attracted by its neighbours
|
||
|
for(long i = 0; i < size; i++)
|
||
|
config[i] = 0.5*previous[i] + 0.25*previous[(i-1) % size]
|
||
|
+ 0.25*previous[(i+1) % size];
|
||
|
|
||
|
stochastic_unit_step(size, config); // actual random walk step
|
||
|
shift_centre_to_origin(size, config); // shift such that the average remains zero
|
||
|
|
||
|
return config;
|
||
|
}
|
||
|
|
||
|
void crw::output(long no, long size, float present[], float extreme[], double avg_el)
|
||
|
{
|
||
|
/* output statistics over the run so far
|
||
|
*/
|
||
|
std::cout << std::setw(12) << no << "\t" << std::setprecision(3) << std::fixed
|
||
|
<< std::setw(6) << elongation(size, present) << " "
|
||
|
<< std::setprecision(7) << std::setw(10) << avg_el << " " << std::setprecision(5)
|
||
|
<< std::setw(9) << elongation(size, extreme) << std::setprecision(3) << "\t\t";
|
||
|
|
||
|
/* display the present configuration, showing up to <el_out_max> element coordinates */
|
||
|
for(long i = 0; (i < size) && (i < el_out_max); i++)
|
||
|
std::cout << std::setw(7) << present[i] << " ";
|
||
|
if(size > el_out_max) std::cout << "...";
|
||
|
std::cout << "\t\t";
|
||
|
|
||
|
/* display the most extreme configuration so far,
|
||
|
* showing up to <el_out_max> element coordinates
|
||
|
*/
|
||
|
for(long i = 0; (i < size) && (i < el_out_max); i++)
|
||
|
std::cout << std::setw(7) << extreme[i] << " ";
|
||
|
if(size > el_out_max) std::cout << "...";
|
||
|
std::cout << "\n";
|
||
|
}
|