Files @ 3e647eb7b5b3
Branch filter:

Location: AENC/switchchain/cpp/switchchain_canonical_properties.cpp - annotation

Tom Bannink
Add improved construction rate dataset and plot
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
786c1ab9a61e
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
aa79d2994c1e
03b85970d933
03b85970d933
03b85970d933
03b85970d933
786c1ab9a61e
03b85970d933
03b85970d933
03b85970d933
786c1ab9a61e
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
aa79d2994c1e
786c1ab9a61e
786c1ab9a61e
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
a410aaa16af7
a410aaa16af7
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
03b85970d933
03b85970d933
03b85970d933
03b85970d933
03b85970d933
03b85970d933
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
a410aaa16af7
a410aaa16af7
a410aaa16af7
a410aaa16af7
a410aaa16af7
a410aaa16af7
32a7f1c13790
32a7f1c13790
aa79d2994c1e
aa79d2994c1e
32a7f1c13790
32a7f1c13790
32a7f1c13790
03b85970d933
03b85970d933
32a7f1c13790
32a7f1c13790
aa79d2994c1e
32a7f1c13790
aa79d2994c1e
a410aaa16af7
a410aaa16af7
a410aaa16af7
a410aaa16af7
a410aaa16af7
a410aaa16af7
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
a410aaa16af7
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
a410aaa16af7
a410aaa16af7
a410aaa16af7
a410aaa16af7
a410aaa16af7
a410aaa16af7
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
32a7f1c13790
#include "exports.hpp"
#include "graph.hpp"
#include "graph_powerlaw.hpp"
#include "graph_spectrum.hpp"
#include "switchchain.hpp"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <numeric>
#include <random>
#include <vector>

double getDSTN(const DegreeSequence& ds) {
    std::vector<std::vector<double>> vals(ds.size());
    for (auto& v : vals) {
        v.resize(ds.size(), 0);
    }

    auto D = 0u;
    for (auto d : ds)
        D += d;

    double factor = 1.0 / double(D);

    for (auto i = 0u; i < ds.size(); ++i) {
        for (auto j = i + 1; j < ds.size(); ++j) {
            vals[i][j] = 1.0 - std::exp(-(ds[i] * ds[j] * factor));
        }
    }

    double result = 0.0;
    for (auto i = 0u; i < ds.size(); ++i) {
        for (auto j = i + 1; j < ds.size(); ++j) {
            for (auto k = j + 1; k < ds.size(); ++k) {
                result += vals[i][j] * vals[j][k] * vals[i][k];
            }
        }
    }
    return result;
}

int main(int argc, char* argv[]) {
    // Simulation parameters
    const int numVerticesMin = 1000;
    const int numVerticesMax = 10000;
    const int numVerticesStep = 1000;

    float tauValues[] = {2.05f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, 2.95f};

    //const int totalDegreeSamples = 5000;

    auto getMixingTime = [](int n, float tau) {
        return int(50.0f * (50.0f - 5.0f * (tau - 2.0f)) * n);
    };
    auto getMeasurements = [](int n, float tau) {
        (void)n;
        (void)tau;
        return 1000;
    };
    auto getMeasureSkip = [](int n, float tau) {
        (void)tau;
        return 30 * n; // Take a sample every ... steps
    };

    // Output file
    std::ofstream outfile;
    if (argc >= 2)
        outfile.open(argv[1]);
    else
        outfile.open("graphdata_canonical_properties.m");
    if (!outfile.is_open()) {
        std::cout << "ERROR: Could not open output file.\n";
        return 1;
    }

    // Output Mathematica-style comment to indicate file contents
    outfile << "(*\n";
    outfile << "n from " << numVerticesMin << " to " << numVerticesMax
            << " step " << numVerticesStep << std::endl;
    outfile << "tauValues: " << tauValues << std::endl;
    outfile << "Canonical degree sequence.\n";
    outfile << "mixingTime: 50 * (50 - 5 (tau - 2)) n\n";
    outfile << "measurements: 1000\n";
    outfile << "measureSkip: 30 n\n";
    outfile << "data:\n";
    outfile << "1: {n,tau}\n";
    outfile << "2: avgTriangles\n";
    outfile << "3: edges\n";
    outfile << "4: dstn\n";
    //outfile << "5: { HH A, HH L, average A, average L }  where for each there is (average of) {lambda1 , lambda1 - lambda2, lambda1/lambda2}\n";
    outfile << "5: empty\n";
    outfile << "6: switching successrate after mixing\n";
    outfile << "7: initial HH triangles\n";
    outfile << "*)" << std::endl;

    // Mathematica does not accept normal scientific notation
    outfile << std::fixed;
    outfile << '{';
    bool outputComma = false;

    Graph g;
    for (int numVertices = numVerticesMin; numVertices <= numVerticesMax;
         numVertices += numVerticesStep) {
        for (float tau : tauValues) {
            DegreeSequence ds;
            generateCanonicalPowerlawGraph(numVertices, tau, g, ds);

            SwitchChain chain;
            if (!chain.initialize(g)) {
                std::cerr << "Could not initialize Markov chain.\n";
                return 1;
            }

            std::cout << "Running (n,tau) = (" << numVertices << ',' << tau
                      << "). " << std::flush;

            // Mix
            int mixingTime = getMixingTime(numVertices, tau);
            for (int i = 0; i < mixingTime; ++i) {
                chain.doMove();
            }

            std::cout << "Mixing done. " << std::flush;

            std::array<double, 3> HHAspectrum;
            std::array<double, 3> HHLspectrum;
            std::array<double, 3> avgAspectrum;
            std::array<double, 3> avgLspectrum;

            //auto getSpectralValues =
            //    [](const std::vector<float> &s) -> std::array<double, 3> {
            //    auto l1 = s[s.size() - 1];
            //    auto l2 = s[s.size() - 2];
            //    return {l1, l1 - l2, l1 / l2};
            //};

            GraphSpectrum gs_start(g);
            GraphSpectrum gs(chain.g);

            HHAspectrum.fill(0);
            HHLspectrum.fill(0);
            //HHAspectrum =
            //    getSpectralValues(gs_start.computeAdjacencySpectrum());
            //HHLspectrum =
            //    getSpectralValues(gs_start.computeLaplacianSpectrum());

            long long trianglesTotal = 0;
            chain.g.getTrackedTriangles() = chain.g.countTriangles();

            int movesDone = 0;
            avgAspectrum.fill(0);
            avgLspectrum.fill(0);
            int measurements = getMeasurements(numVertices, tau);
            int measureSkip = getMeasureSkip(numVertices, tau);
            for (int i = 0; i < measurements; ++i) {
                for (int j = 0; j < measureSkip; ++j)
                    if (chain.doMove(true))
                        ++movesDone;
                trianglesTotal += chain.g.getTrackedTriangles();
                //auto sA = getSpectralValues(gs.computeAdjacencySpectrum());
                //auto sL = getSpectralValues(gs.computeLaplacianSpectrum());
                //for (auto i = 0u; i < 3; ++i) {
                //    avgAspectrum[i] += sA[i];
                //    avgLspectrum[i] += sL[i];
                //}
            }
            float avgTriangles = float(trianglesTotal) / float(measurements);
            float successrate =
                float(movesDone) / float(measurements * measureSkip);
            for (auto &f : avgAspectrum)
                f /= float(measurements);
            for (auto &f : avgLspectrum)
                f /= float(measurements);

            std::cout << "Measuring done. " << std::flush;

            if (outputComma)
                outfile << ',' << '\n';
            outputComma = true;

            outfile << '{' << '{' << numVertices << ',' << tau << '}';
            outfile << ',' << avgTriangles;
            outfile << ',' << g.edgeCount();
            outfile << ',' << getDSTN(ds);
            outfile << ",{}";
            //outfile << ',' << '{' << HHAspectrum;
            //outfile << ',' << HHLspectrum;
            //outfile << ',' << avgAspectrum;
            //outfile << ',' << avgLspectrum;
            //outfile << '}';
            outfile << ',' << successrate;
            outfile << ',' << g.countTriangles();
            outfile << '}' << std::flush;

            std::cout << "Output done." << std::endl;
        }
    }
    outfile << '}';
    return 0;
}