#pragma once
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include "isoMath.h"
#include "pod_vector.h"
namespace IsoSpec
{
inline double combinedSum(
const int* conf, const std::vector<double>** valuesContainer, int dimNumber
){
double res = 0.0;
for(int i = 0; i < dimNumber; i++)
res += (*(valuesContainer[i]))[conf[i]];
return res;
}
inline double combinedSum(
const int* conf, const pod_vector<double>** valuesContainer, int dimNumber
){
double res = 0.0;
for(int i = 0; i < dimNumber; i++)
res += (*(valuesContainer[i]))[conf[i]];
return res;
}
inline int* getConf(void* conf)
{
return reinterpret_cast<int*>(
reinterpret_cast<char*>(conf) + sizeof(double)
);
}
inline double getLProb(void* conf)
{
double ret = *reinterpret_cast<double*>(conf);
return ret;
}
inline double unnormalized_logProb(const int* conf, const double* logProbs, int dim)
{
double res = 0.0;
for(int i = 0; i < dim; i++)
res += minuslogFactorial(conf[i]) + conf[i] * logProbs[i];
return res;
}
inline double calc_mass(const int* conf, const double* masses, int dim)
{
double res = 0.0;
for(int i = 0; i < dim; i++)
{
res += conf[i] * masses[i];
}
return res;
}
template<typename T> void printArray(const T* array, size_t size, const char* prefix = "")
{
if (strlen(prefix) > 0)
std::cout << prefix << " ";
for (size_t i = 0; i < size; i++)
std::cout << array[i] << " ";
std::cout << std::endl;
}
template<typename T> void printVector(const std::vector<T>& vec)
{
printArray<T>(vec.data(), vec.size());
}
template<typename T> void printVector(const pod_vector<T>& vec)
{
printArray<T>(vec.data(), vec.size());
}
template<typename T> void printOffsets(const T** array, size_t size, const T* offset, const char* prefix = "")
{
if (strlen(prefix) > 0)
std::cout << prefix << " ";
for (size_t i = 0; i < size; i++)
std::cout << array[i] - offset << " ";
std::cout << std::endl;
}
template<typename T> void printNestedArray(const T** array, const int* shape, size_t size)
{
for (size_t i = 0; i < size; i++)
printArray(array[i], shape[i]);
std::cout << std::endl;
}
void* quickselect(void** array, size_t n, size_t start, size_t end);
template <typename T> inline static T* array_copy(const T* A, size_t size)
{
T* ret = new T[size];
if(size > 0)
memcpy(ret, A, size*sizeof(T));
return ret;
}
template <typename T> inline static T* array_copy_malloc(const T* A, size_t size)
{
T* ret = reinterpret_cast<T*>(malloc(size * sizeof(T)));
if(ret == nullptr)
throw std::bad_alloc();
memcpy(ret, A, size*sizeof(T));
return ret;
}
template <typename T> static T* array_copy_nptr(const T* A, size_t size)
{
if(A == nullptr)
return nullptr;
return array_copy(A, size);
}
template <typename T> static T* array_copy_nptr_malloc(const T* A, size_t size)
{
if(A == nullptr)
return nullptr;
return array_copy_malloc(A, size);
}
template<typename T> void dealloc_table(T* tbl, int dim)
{
for(int i = 0; i < dim; i++)
{
delete tbl[i];
}
delete[] tbl;
}
template<typename T> void realloc_append(T** array, T what, size_t old_array_size)
{
T* newT = new T[old_array_size+1];
if(old_array_size > 0)
memcpy(newT, *array, old_array_size*sizeof(T));
newT[old_array_size] = what;
delete[] *array;
*array = newT;
}
template<typename T> size_t* get_order(T* order_array, size_t N)
{
size_t* arr = new size_t[N];
for(size_t ii = 0; ii < N; ii++)
arr[ii] = ii;
std::sort(arr, arr + N, [&](size_t i, size_t j) { return order_array[i] < order_array[j]; });
return arr;
}
template<typename T> size_t* get_inverse_order(T* order_array, size_t N)
{
size_t* arr = new size_t[N];
for(size_t ii = 0; ii < N; ii++)
arr[ii] = ii;
std::sort(arr, arr + N, [&](size_t i, size_t j) { return order_array[i] > order_array[j]; });
return arr;
}
template<typename TA, typename TB> void impose_order(size_t* O, size_t N, TA* A, TB* B)
{
for(size_t ii = 0; ii < N; ii++)
{
if(ii != O[ii])
{
size_t curr_ii = ii;
TA ta = A[ii];
TB tb = B[ii];
size_t next_ii = O[ii];
while(next_ii != ii)
{
A[curr_ii] = A[next_ii];
B[curr_ii] = B[next_ii];
O[curr_ii] = curr_ii;
curr_ii = next_ii;
next_ii = O[next_ii];
}
A[curr_ii] = ta;
B[curr_ii] = tb;
O[curr_ii] = curr_ii;
}
}
}
}