<commit_before>#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <complex>
#include <functional>

#include <multiplex_gmhmm.h>
#include <nsga2.h>

#define DPRINTC(C) printf(#C " = %c\n", (C))
#define DPRINTS(S) printf(#S " = %s\n", (S))
#define DPRINTD(D) printf(#D " = %d\n", (D))
#define DPRINTLLD(LLD) printf(#LLD " = %lld\n", (LLD))
#define DPRINTLF(LF) printf(#LF " = %.5lf\n", (LF))

using namespace std;
typedef unsigned int uint;
typedef long long lld;
typedef unsigned long long llu;

// initialise a random multiplex GMHMM
MultiplexGMHMM::MultiplexGMHMM(int n, int obs, int L) : n(n), obs(obs), L(L)
{
    this -> layers.resize(L);
    for (int i=0;i<L;i++)
    {
        this -> layers[i] = new GMHMM(n, obs);
    }
    
    this -> omega = new double*[L];
    for (int i=0;i<L;i++)
    {
        this -> omega[i] = new double[L];
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] = (i == j) ? 1.0 : 0.0;
        }
    }
}

// initialise a multiplex GMHMM from parameters
MultiplexGMHMM::MultiplexGMHMM(int n, int obs, int L, vector<GMHMM*> layers, double **omega) : n(n), obs(obs), L(L)
{
    this -> layers.resize(L);
    for (int i=0;i<L;i++)
    {
        this -> layers[i] = new GMHMM(layers[i]);
    }

    this -> omega = new double*[L];
    for (int i=0;i<L;i++)
    {
        this -> omega[i] = new double[L];
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] = omega[i][j];
        }
    }
}

// Copy constructor
MultiplexGMHMM::MultiplexGMHMM(MultiplexGMHMM *m_gmhmm) : n(m_gmhmm -> n), obs(m_gmhmm -> obs), L(m_gmhmm -> L)
{
    layers.resize(m_gmhmm -> L);
    for (int i=0;i<m_gmhmm->L;i++)
    {
        layers[i] = new GMHMM(m_gmhmm -> layers[i]);
    }

    omega = new double*[m_gmhmm -> L];
    for (int i=0;i<m_gmhmm->L;i++)
    {
        omega[i] = new double[m_gmhmm -> L];
        for (int j=0;j<m_gmhmm->L;j++)
        {
            omega[i][j] = m_gmhmm -> omega[i][j];
        }
    }
}

MultiplexGMHMM::~MultiplexGMHMM()
{
    for (int i=0;i<L;i++) delete layers[i];
    for (int i=0;i<L;i++) delete[] omega[i];
    delete[] omega;
}

// Setter for the interlayer transition matrix; useful while training
void MultiplexGMHMM::set_omega(double **omega)
{
    for (int i=0;i<L;i++)
    {
        double sum = 0.0;
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] = omega[i][j];
            sum += omega[i][j];
        }
        // Perform normalisation here, just in case
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] /= sum;
        }
    }
}

// (Re)randomise the model parameters
void MultiplexGMHMM::reset()
{
    for (int l=0;l<L;l++)
    {
        layers[l] -> reset();
    }

    for (int i=0;i<L;i++)
    {
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] = (i == j) ? 1.0 : 0.0;
        }
    }
}

// Train the model parameters from a given training set
void MultiplexGMHMM::train(vector<vector<pair<int, vector<double> > > > &train_set, nsga2_params &nsga_p, baumwelch_params &bw_p)
{
    // Train all the layers individually (as before)<commit_msg>Randomisation to omega now more explicit.<commit_after>#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <complex>
#include <functional>

#include <multiplex_gmhmm.h>
#include <nsga2.h>

#define DPRINTC(C) printf(#C " = %c\n", (C))
#define DPRINTS(S) printf(#S " = %s\n", (S))
#define DPRINTD(D) printf(#D " = %d\n", (D))
#define DPRINTLLD(LLD) printf(#LLD " = %lld\n", (LLD))
#define DPRINTLF(LF) printf(#LF " = %.5lf\n", (LF))

using namespace std;
typedef unsigned int uint;
typedef long long lld;
typedef unsigned long long llu;

// define a RNG for U(0, 1)
default_random_engine gen_mux;
uniform_real_distribution<double> rnd_real_mux(0.0, 1.0);

// initialise a random multiplex GMHMM
MultiplexGMHMM::MultiplexGMHMM(int n, int obs, int L) : n(n), obs(obs), L(L)
{
    this -> layers.resize(L);
    for (int i=0;i<L;i++)
    {
        this -> layers[i] = new GMHMM(n, obs);
    }
    
    this -> omega = new double*[L];
    for (int i=0;i<L;i++)
    {
        this -> omega[i] = new double[L];
        double total = 0.0;
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] = rnd_real_mux(gen_mux);
            total += this -> omega[i][j];
        }
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] /= total;
        }
    }
}

// initialise a multiplex GMHMM from parameters
MultiplexGMHMM::MultiplexGMHMM(int n, int obs, int L, vector<GMHMM*> layers, double **omega) : n(n), obs(obs), L(L)
{
    this -> layers.resize(L);
    for (int i=0;i<L;i++)
    {
        this -> layers[i] = new GMHMM(layers[i]);
    }

    this -> omega = new double*[L];
    for (int i=0;i<L;i++)
    {
        this -> omega[i] = new double[L];
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] = omega[i][j];
        }
    }
}

// Copy constructor
MultiplexGMHMM::MultiplexGMHMM(MultiplexGMHMM *m_gmhmm) : n(m_gmhmm -> n), obs(m_gmhmm -> obs), L(m_gmhmm -> L)
{
    layers.resize(m_gmhmm -> L);
    for (int i=0;i<m_gmhmm->L;i++)
    {
        layers[i] = new GMHMM(m_gmhmm -> layers[i]);
    }

    omega = new double*[m_gmhmm -> L];
    for (int i=0;i<m_gmhmm->L;i++)
    {
        omega[i] = new double[m_gmhmm -> L];
        for (int j=0;j<m_gmhmm->L;j++)
        {
            omega[i][j] = m_gmhmm -> omega[i][j];
        }
    }
}

MultiplexGMHMM::~MultiplexGMHMM()
{
    for (int i=0;i<L;i++) delete layers[i];
    for (int i=0;i<L;i++) delete[] omega[i];
    delete[] omega;
}

// Setter for the interlayer transition matrix; useful while training
void MultiplexGMHMM::set_omega(double **omega)
{
    for (int i=0;i<L;i++)
    {
        double sum = 0.0;
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] = omega[i][j];
            sum += omega[i][j];
        }
        // Perform normalisation here, just in case
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] /= sum;
        }
    }
}

// (Re)randomise the model parameters
void MultiplexGMHMM::reset()
{
    for (int l=0;l<L;l++)
    {
        layers[l] -> reset();
    }

    for (int i=0;i<L;i++)
    {
        double total = 0.0;
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] = rnd_real_mux(gen_mux);
            total += this -> omega[i][j];
        }
        for (int j=0;j<L;j++)
        {
            this -> omega[i][j] /= total;
        }
    }
}

// Train the model parameters from a given training set
void MultiplexGMHMM::train(vector<vector<pair<int, vector<double> > > > &train_set, nsga2_params &nsga_p, baumwelch_params &bw_p)
{
    // Train all the layers individually (as before)
{'fraction_non_alphanumeric': 0.186993006993007, 'fraction_numerical': 0.008951048951048951, 'mean_word_length': 2.4882926829268293, 'pattern_counts': {'":': 0, '<': 88, '<?xml version=': 0, '>': 106, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1069396', 'n_tokens_mistral': 2995, 'n_tokens_neox': 2851, 'n_words': 637}