forked from clelidm/MinCompSpin_Greedy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLogL.cpp
More file actions
106 lines (87 loc) · 4.06 KB
/
Copy pathLogL.cpp
File metadata and controls
106 lines (87 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#define _USE_MATH_DEFINES
#include <bitset>
#include <cmath> /* tgamma */
#include <map>
using namespace std;
#include "data.h"
/******************************************************************************/
/**************** Log-likelihood (LogL) of a complete model ******************/
/******************************************************************************/
// Compute the log-likelihood of a complete model on Kset:
// This function is mainly used for call by `LogL_SC_PartMCM`,
// but can also be used to compute the log-likelihood of a complete model
//
double LogL_CM(map<__int128_t, unsigned int > Kset, unsigned int N)
{
double LogL = 0;
map<__int128_t, unsigned int >::iterator it;
unsigned int Ncontrol = 0; // for control
unsigned int Ks = 0;
double Nd = N;
for (it = Kset.begin(); it!=Kset.end(); ++it)
{
Ks = (it->second); Ncontrol += Ks;
if (Ks == 0) {cout << "problem Ks = 0 for some mu_m" << endl; }
LogL += (Ks * log((double) Ks / Nd) );
}
if (Ncontrol != N) { cout << "Error in function 'LogLikelihood_SCforMCM': Ncontrol != N" << endl; }
return LogL;
}
/******************************************************************************/
/***************************** Log-likelihood (LogL) **************************/
/*********************** of a sub-complete part of a MCM ******************/
/******************************************************************************/
// Compute the log-likelihood of the sub-complete part (of an MCM) defined by Ai.
// This function could be also used directly by the user
// to compute the log-likelihood of a sub-complete model
double LogL_SubCM(map<__int128_t, unsigned int> Kset, __int128_t Ai, unsigned int N, bool print_bool = false)
{
map<__int128_t, unsigned int>::iterator it;
map<__int128_t, unsigned int > Kset_new;
__int128_t s; // state
unsigned int ks=0; // number of time state s appear in the dataset
if (print_bool) {
cout << endl << "--->> Build Kset for SC Model based on " << bitset<n>(Ai) << " for MCM.." << endl;
}
//Build Kset_new:
for (it = Kset.begin(); it!=Kset.end(); ++it)
{
s = it->first; // initial state s
ks = it->second; // # of times s appears in the data set
if (print_bool) { cout << bitset<n>(s) << " \t" ; }
s &= Ai; // troncated state: take only the bits indicated by Ai
// sig_m = bitset<m>(bitset<m>(mu).to_string()).to_ulong(); //bitset<m>(mu).to_ulong(); // mu|m
if (print_bool) { cout << bitset<n>(s) << endl; }
Kset_new[s] += ks;
//Kset[mu_m].second.push_back(make_pair(mu, N_mu));
}
if (print_bool) { cout << endl; }
return LogL_CM(Kset_new, N);
}
/******************************************************************************/
/******************** Log-likelihood (LogL) of a MCM *************************/
/******************************************************************************/
//check if *Partition* is an actual partition of the basis elements,
// i.e., that no basis element appears in more than 1 part of the partition.
// i.e., that each basis element only appears in a single part of the partition.
//bool check_partition(map<uint32_t, uint32_t> Partition);
double LogL_MCM(map<__int128_t, unsigned int> Kset, map<unsigned int, __int128_t> Partition, unsigned int N, unsigned int r = n, bool print_bool = false)
//double LogL_MCM(map<uint32_t, unsigned int > Kset, map<uint32_t, uint32_t> Partition, unsigned int N, bool print_bool = false)
{
//if (!check_partition(Partition)) {cout << "Error, the argument is not a partition." << endl; return 0; }
//else
//{
double LogL = 0;
unsigned int rank = 0;
map<unsigned int, __int128_t>::iterator Part;
for (Part = Partition.begin(); Part != Partition.end(); Part++)
{
bitset<n> hi{ static_cast<unsigned long long>((*Part).second >> 64) },
lo{ static_cast<unsigned long long>((*Part).second) },
bits{ (hi << 64) | lo };
LogL += LogL_SubCM(Kset, (*Part).second, N);
rank += bits.count();
}
return LogL - ((double) (N * (n-rank))) * log(2.);
//}
}