Update code
This commit is contained in:
@@ -21,7 +21,6 @@
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
|
||||
// Faster modulo
|
||||
#define INDEX(I, N) (I + N) % N
|
||||
|
||||
// Indeces for the neighbor matrix.
|
||||
@@ -50,7 +49,7 @@ private:
|
||||
* for the left and upper neighbor, and we can use the same column for the
|
||||
* right and lower neighbor.
|
||||
* */
|
||||
arma::Mat<uint> neighbors;
|
||||
arma::Mat<int> neighbors;
|
||||
|
||||
/** @brief A hash map containing all possible energy changes.
|
||||
* */
|
||||
@@ -62,15 +61,15 @@ private:
|
||||
|
||||
/** @brief Size of the lattice.
|
||||
* */
|
||||
uint L;
|
||||
int L;
|
||||
|
||||
/** @brief The current energy state. unit: \f$ J \f$.
|
||||
* */
|
||||
double E;
|
||||
int E;
|
||||
|
||||
/** @brief The current magnetic strength. unit: Unitless.
|
||||
* */
|
||||
double M;
|
||||
int M;
|
||||
|
||||
/** @brief Initialize the lattice with a random distribution of 1s and
|
||||
* -1s.
|
||||
@@ -103,7 +102,7 @@ public:
|
||||
* @param L The size of the lattice.
|
||||
* @param T The temperature for the system.
|
||||
* */
|
||||
IsingModel(uint L, double T);
|
||||
IsingModel(int L, double T);
|
||||
|
||||
/** @brief Constructor for the Ising model.
|
||||
*
|
||||
@@ -111,23 +110,23 @@ public:
|
||||
* @param T The temperature for the system.
|
||||
* @param val The value to set for all spins.
|
||||
* */
|
||||
IsingModel(uint L, double T, int val);
|
||||
IsingModel(int L, double T, int val);
|
||||
|
||||
/** @brief The Metropolis algorithm.
|
||||
* */
|
||||
data_t Metropolis(std::mt19937 &engine);
|
||||
data_t Metropolis();
|
||||
|
||||
/** @brief Get the current energy.
|
||||
*
|
||||
* @return double
|
||||
* */
|
||||
double get_E();
|
||||
int get_E();
|
||||
|
||||
/** @brief Get the current magnetization.
|
||||
*
|
||||
* @return double
|
||||
* */
|
||||
double get_M();
|
||||
int get_M();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,64 +15,105 @@
|
||||
#include <sys/types.h>
|
||||
#include <type_traits>
|
||||
|
||||
/** @brief Data structure that contains the data needed for the project*/
|
||||
struct data_t {
|
||||
double E = 0.; ///< The expected energy
|
||||
double M = 0.; ///< The expected magnetization
|
||||
double E2 = 0.; ///< The expected variance of the energy
|
||||
double M2 = 0.; ///< The expected variance of magnetization
|
||||
double M_abs = 0.; ///< The expected absolute magnetization
|
||||
class data_t {
|
||||
public:
|
||||
double E, M, E2, M2, M_abs;
|
||||
|
||||
data_t()
|
||||
{
|
||||
this->E = 0.;
|
||||
this->E2 = 0.;
|
||||
this->M = 0.;
|
||||
this->M2 = 0.;
|
||||
this->M_abs = 0.;
|
||||
}
|
||||
|
||||
data_t(double E, double E2, double M, double M2, double M_abs)
|
||||
{
|
||||
this->E = E;
|
||||
this->E2 = E2;
|
||||
this->M = M;
|
||||
this->M2 = M2;
|
||||
this->M_abs = M_abs;
|
||||
}
|
||||
|
||||
template <class T> data_t operator/(T num)
|
||||
{
|
||||
data_t res;
|
||||
res.E = this->E / (double)num;
|
||||
res.E2 = this->E2 / (double)num;
|
||||
res.M = this->M / (double)num;
|
||||
res.M2 = this->M2 / (double)num;
|
||||
res.M_abs = this->M_abs / (double)num;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class T> data_t& operator/=(T num)
|
||||
{
|
||||
this->E /= (double)num;
|
||||
this->E2 /= (double)num;
|
||||
this->M /= (double)num;
|
||||
this->M2 /= (double)num;
|
||||
this->M_abs /= (double)num;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T> data_t operator*(T num)
|
||||
{
|
||||
data_t res;
|
||||
res.E = this->E * (double)num;
|
||||
res.E2 = this->E2 * (double)num;
|
||||
res.M = this->M * (double)num;
|
||||
res.M2 = this->M2 * (double)num;
|
||||
res.M_abs = this->M_abs * (double)num;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template <class T> data_t& operator*=(T num)
|
||||
{
|
||||
this->E *= (double)num;
|
||||
this->E2 *= (double)num;
|
||||
this->M *= (double)num;
|
||||
this->M2 *= (double)num;
|
||||
this->M_abs *= (double)num;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
data_t operator+(const data_t &b)
|
||||
{
|
||||
data_t res;
|
||||
res.E = this->E + b.E;
|
||||
res.E2 = this->E2 + b.E2;
|
||||
res.M = this->M + b.M;
|
||||
res.M2 = this->M2 + b.M2;
|
||||
res.M_abs = this->M_abs + b.M_abs;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
data_t& operator+=(const data_t &b)
|
||||
{
|
||||
this->E += b.E;
|
||||
this->E2 += b.E2;
|
||||
this->M += b.M;
|
||||
this->M2 += b.M2;
|
||||
this->M_abs += b.M_abs;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T> void operator=(T num)
|
||||
{
|
||||
this->E = (double)num;
|
||||
this->E2 = (double)num;
|
||||
this->M = (double)num;
|
||||
this->M2 = (double)num;
|
||||
this->M_abs = (double)num;
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief Define dividing data_t by a number
|
||||
*
|
||||
* @param data The data to divide
|
||||
* @param num The number to divide data by
|
||||
*
|
||||
* @return data_t
|
||||
* */
|
||||
template <class T>
|
||||
data_t operator/(const data_t &data, T num);
|
||||
|
||||
// Explicit instantiation
|
||||
extern template data_t operator/(const data_t &, uint);
|
||||
extern template data_t operator/(const data_t &, ulong);
|
||||
extern template data_t operator/(const data_t &,int);
|
||||
extern template data_t operator/(const data_t &,double);
|
||||
|
||||
|
||||
/** @brief Define /= on data_t by a number.
|
||||
*
|
||||
* @param data The data to divide
|
||||
* @param num The number to divide data by
|
||||
*
|
||||
* @return data_t
|
||||
* */
|
||||
template <class T>
|
||||
data_t& operator/=(data_t &data, T num);
|
||||
|
||||
// Explicit instantiation
|
||||
extern template data_t& operator/=(data_t &, uint);
|
||||
extern template data_t& operator/=(data_t &, ulong);
|
||||
extern template data_t& operator/=(data_t &,int);
|
||||
extern template data_t& operator/=(data_t &,double);
|
||||
|
||||
/** @brief Define + on data_t by a data_t.
|
||||
*
|
||||
* @param a The left side
|
||||
* @param b The right side
|
||||
*
|
||||
* @return data_t
|
||||
* */
|
||||
data_t operator+(const data_t &a, const data_t &b);
|
||||
|
||||
/** @brief Define += on data_t by a data_t.
|
||||
*
|
||||
* @param a The left side
|
||||
* @param b The right side
|
||||
*
|
||||
* @return data_t
|
||||
* */
|
||||
data_t& operator+=(data_t &a, const data_t &b);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,31 +18,21 @@
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <omp.h>
|
||||
|
||||
#define BURN_IN_TIME 1000
|
||||
//#define BURN_IN_TIME 12500
|
||||
#define BURN_IN_TIME 5000
|
||||
|
||||
#define EPS_2 (-2 * std::sinh(8.)) / (std::cosh(8.) + 3)
|
||||
|
||||
#define MAG_2 (std::exp(8.) + 1) / (2 * cosh(8.) + 3)
|
||||
|
||||
#define CV_2 \
|
||||
16 \
|
||||
* (3 * std::cosh(8.) + std::cosh(8.) * std::cosh(8.) \
|
||||
- std::sinh(8.) * std::sinh(8.)) \
|
||||
/ ((std::cosh(8.) + 3) * (std::cosh(8.) + 3))
|
||||
|
||||
#define X_2 \
|
||||
(3 * std::exp(8.) + std::exp(-8.) + 3) \
|
||||
/ ((std::cosh(8.) + 3) * (std::cosh(8.) + 3))
|
||||
#pragma omp declare reduction(+: data_t: omp_out += omp_in)
|
||||
|
||||
/** @brief Test numerical data with analytical data.
|
||||
*
|
||||
* @param tol The tolerance between the analytical and numerical solution.
|
||||
* @param max_cycles The max number of Monte Carlo cycles.
|
||||
*
|
||||
* return uint
|
||||
* return int
|
||||
* */
|
||||
uint test_2x2_lattice(double tol, uint max_cycles);
|
||||
int test_2x2_lattice(double tol, int max_cycles);
|
||||
|
||||
/** @brief Write the expected values for each Monte Carlo cycles to file.
|
||||
*
|
||||
@@ -51,7 +41,18 @@ uint test_2x2_lattice(double tol, uint max_cycles);
|
||||
* @param cycles The amount of Monte Carlo cycles to do
|
||||
* @param filename The file to write to
|
||||
* */
|
||||
void monte_carlo_progression(double T, uint L, uint cycles,
|
||||
void monte_carlo_progression(double T, int L, int cycles,
|
||||
const std::string filename);
|
||||
|
||||
/** @brief Write the expected values for each Monte Carlo cycles to file.
|
||||
*
|
||||
* @param T Temperature
|
||||
* @param L The size of the lattice
|
||||
* @param cycles The amount of Monte Carlo cycles to do
|
||||
* @param value The value to set the elements in the lattice
|
||||
* @param filename The file to write to
|
||||
* */
|
||||
void monte_carlo_progression(double T, int L, int cycles, int value,
|
||||
const std::string filename);
|
||||
|
||||
/** @brief Estimate the probability distribution for the energy.
|
||||
@@ -61,26 +62,29 @@ void monte_carlo_progression(double T, uint L, uint cycles,
|
||||
* @param cycles The amount of Monte Carlo cycles to do
|
||||
* @param filename The file to write to
|
||||
* */
|
||||
void pd_estimate(double T, uint L, uint cycles, const std::string filename);
|
||||
void pd_estimate(double T, int L, int cycles, const std::string filename);
|
||||
|
||||
/** @brief Execute the Metropolis algorithm for a certain amount of Monte
|
||||
/** @brief Execute the Metropolis algorithm for a certain amount of Monte
|
||||
* Carlo cycles.
|
||||
*
|
||||
* @param data The data to store the results
|
||||
* @param L The size of the lattice
|
||||
* @param T The Temperature for the Ising model
|
||||
* @param cycles The amount of Monte Carlo cycles to do*/
|
||||
void monte_carlo_serial(data_t &data, uint L, double T, uint cycles);
|
||||
|
||||
/** @brief Execute the Metropolis algorithm for a certain amount of Monte
|
||||
* Carlo cycles in parallel.
|
||||
*
|
||||
* @param data The data to store the results
|
||||
* @param L The size of the lattice
|
||||
* @param T The Temperature for the Ising model
|
||||
* @param cycles The amount of Monte Carlo cycles to do
|
||||
*
|
||||
* @return data_t
|
||||
* */
|
||||
void monte_carlo_parallel(data_t &data, uint L, double T, uint cycles);
|
||||
data_t monte_carlo_serial(int L, double T, int cycles);
|
||||
|
||||
/** @brief Execute the Metropolis algorithm for a certain amount of Monte
|
||||
* Carlo cycles in parallel.
|
||||
*
|
||||
* @param L The size of the lattice
|
||||
* @param T The Temperature for the Ising model
|
||||
* @param cycles The amount of Monte Carlo cycles to do
|
||||
*
|
||||
* @return data_t
|
||||
* */
|
||||
data_t monte_carlo_parallel(int L, double T, int cycles);
|
||||
|
||||
/** @brief Perform the MCMC algorithm using a range of temperatures.
|
||||
*
|
||||
@@ -92,8 +96,8 @@ void monte_carlo_parallel(data_t &data, uint L, double T, uint cycles);
|
||||
* @param outfile The file to write the data to
|
||||
* */
|
||||
void phase_transition(
|
||||
uint L, double start_T, double end_T, uint points_T,
|
||||
std::function<void(data_t &, uint, double, uint)> monte_carlo,
|
||||
int L, double start_T, double end_T, int points_T,
|
||||
std::function<data_t(int, double, int)> monte_carlo,
|
||||
std::string outfile);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
* @brief A small test library.
|
||||
*
|
||||
* @details This a small testing library that is tailored for the needs of the
|
||||
* project.
|
||||
* project. Anything that is in the details namespace should not be used
|
||||
* directly, or else it might cause undefined behavior if not used correctly.
|
||||
*
|
||||
* @bug No known bugs
|
||||
* */
|
||||
@@ -90,7 +91,7 @@ template <class T,
|
||||
class = typename std::enable_if<std::is_arithmetic<T>::value>::type>
|
||||
static bool close_to(T a, T b, double tol = 1e-8)
|
||||
{
|
||||
return std::abs(a - b) < tol;
|
||||
return std::fabs(a - b) < tol;
|
||||
}
|
||||
|
||||
/** @brief Test if two armadillo matrices/vectors are equal.
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
* @brief Function prototypes and macros that are useful.
|
||||
*
|
||||
* These utility function are mainly for convenience and aren't directly
|
||||
* related to the project.
|
||||
* related to the project. Anything that is in the details namespace should
|
||||
* not be used directly, or else it might cause undefined behavior if not used
|
||||
* correctly.
|
||||
*
|
||||
* @bug No known bugs
|
||||
* */
|
||||
@@ -47,7 +49,7 @@ namespace details {
|
||||
*
|
||||
* @details This function should only be used for the __METHOD_NAME__ macro,
|
||||
* since it takes the output from __PRETTY_FUNCTION__ and strips the return
|
||||
* type.
|
||||
* type.
|
||||
*
|
||||
* @param pretty_function The string from __PRETTY_FUNCTION__
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user