66 lines
1.7 KiB
C++
66 lines
1.7 KiB
C++
#include <iostream>
|
|
#include <iomanip>
|
|
|
|
inline int sign(int i) {
|
|
return i < 0 ? -1 : i > 0;
|
|
}
|
|
|
|
inline int& E(int *x, int row, int col) {
|
|
return x[row * (row + 1) / 2 + col];
|
|
}
|
|
|
|
int iter(int *v, int *diff) {
|
|
// enforce boundary conditions
|
|
E(v, 0, 0) = 151;
|
|
E(v, 2, 0) = 40;
|
|
E(v, 4, 1) = 11;
|
|
E(v, 4, 3) = 4;
|
|
|
|
// calculate difference from equilibrium
|
|
for (auto i = 1u; i < 5u; i++)
|
|
for (auto j = 0u; j <= i; j++) {
|
|
E(diff, i, j) = 0;
|
|
if (j < i)
|
|
E(diff, i, j) += E(v, i - 1, j) - E(v, i, j + 1) - E(v, i, j);
|
|
if (j)
|
|
E(diff, i, j) += E(v, i - 1, j - 1) - E(v, i, j - 1) - E(v, i, j);
|
|
}
|
|
|
|
for (auto i = 0u; i < 4u; i++)
|
|
for (auto j = 0u; j < i; j++)
|
|
E(diff, i, j) += E(v, i + 1, j) + E(v, i + 1, j + 1) - E(v, i, j);
|
|
|
|
E(diff, 4, 2) += E(v, 4, 0) + E(v, 4, 4) - E(v, 4, 2);
|
|
|
|
// do feedback, check if we are done
|
|
uint sum;
|
|
int e = 0;
|
|
for (auto i = sum = 0u; i < 15u; i++) {
|
|
sum += !!sign(e = diff[i]);
|
|
|
|
// 1/5-ish feedback strength on average. These numbers are highly magical, depending on nodes' connectivities
|
|
if (e >= 4 || e <= -4)
|
|
v[i] += e / 5;
|
|
else if (rand() < RAND_MAX / 4)
|
|
v[i] += sign(e);
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
void show(int *x) {
|
|
for (auto i = 0u; i < 5u; i++)
|
|
for (auto j = 0u; j <= i; j++)
|
|
std::cout << std::setw(4u) << *(x++) << (j < i ? ' ' : '\n');
|
|
}
|
|
|
|
int main() {
|
|
int v[15] = { 0 }, diff[15] = { 0 };
|
|
for (auto i = 1u, s = 1u; s; i++) {
|
|
s = iter(v, diff);
|
|
std::cout << "pass " << i << ": " << s << std::endl;
|
|
}
|
|
show(v);
|
|
|
|
return 0;
|
|
}
|