Make some changes

- Add new programs
- Add command line args
- Add Usage to guide user on how to use programs
This commit is contained in:
Cory Balaton 2023-12-04 12:36:29 +01:00
parent 1089c2d110
commit 1762fc87ad
No known key found for this signature in database
GPG Key ID: 3E5FCEBFD80F432B
10 changed files with 464 additions and 59 deletions

View File

@ -31,8 +31,8 @@ namespace montecarlo {
* @param cycles The amount of Monte Carlo cycles to do
* @param filename The file to write to
* */
void progression(double T, int L, int cycles,
const std::string filename);
void progression(double T, int L, int cycles, const std::string filename,
int burn_in_time = BURN_IN_TIME);
/** @brief Write the expected values for each Monte Carlo cycles to file.
*
@ -43,7 +43,7 @@ void progression(double T, int L, int cycles,
* @param filename The file to write to
* */
void progression(double T, int L, int cycles, int value,
const std::string filename);
const std::string filename, int burn_in_time = BURN_IN_TIME);
/** @brief Estimate the probability distribution for the energy.
*
@ -52,8 +52,8 @@ void progression(double T, int L, int cycles, int value,
* @param cycles The amount of Monte Carlo cycles to do
* @param filename The file to write to
* */
void pd_estimate(double T, int L, int cycles,
const std::string filename);
void pd_estimate(double T, int L, int cycles, const std::string filename,
int burn_in_time = BURN_IN_TIME);
/** @brief Execute the Metropolis algorithm for a certain amount of Monte
* Carlo cycles.
@ -64,7 +64,8 @@ void pd_estimate(double T, int L, int cycles,
*
* @return data_t
* */
data_t mcmc_serial(int L, double T, int cycles, int burn_in_time = BURN_IN_TIME);
data_t mcmc_serial(int L, double T, int cycles,
int burn_in_time = BURN_IN_TIME);
/** @brief Execute the Metropolis algorithm for a certain amount of Monte
* Carlo cycles in parallel.
@ -75,7 +76,8 @@ data_t mcmc_serial(int L, double T, int cycles, int burn_in_time = BURN_IN_TIME)
*
* @return data_t
* */
data_t mcmc_parallel(int L, double T, int cycles, int burn_in_time = BURN_IN_TIME);
data_t mcmc_parallel(int L, double T, int cycles,
int burn_in_time = BURN_IN_TIME);
/** @brief Perform the MCMC algorithm using a range of temperatures.
*
@ -86,8 +88,8 @@ data_t mcmc_parallel(int L, double T, int cycles, int burn_in_time = BURN_IN_TIM
* @param monte_carlo Which Monte Carlo implementation to use
* @param outfile The file to write the data to
* */
void
phase_transition(int L, double start_T, double end_T, int points_T, int cycles,
void phase_transition(int L, double start_T, double end_T, int points_T,
int cycles,
std::function<data_t(int, double, int, int)> monte_carlo,
std::string outfile, int burn_in_time = BURN_IN_TIME);
}; // namespace montecarlo

View File

@ -114,6 +114,21 @@ bool mkpath(std::string path, int mode = 0777);
* */
std::string dirname(const std::string &path);
/** @brief Take 2 strings and concatenate them and make sure there is a
* directory separator (/) between them.
*
* @details This function doesn't care whether or not the values given as
* parameters are valid path strings. It is the responsibility of the user to make
* sure that the values given are valid path strings.
* The function only guarantees that the output string is a valid path string.
*
* @param left The left hand side of the result string
* @param right The right hand side of the result string
*
* @return string
* */
std::string concatpath(const std::string &left, const std::string &right);
} // namespace utils
#endif

View File

@ -13,6 +13,8 @@
#include "monte_carlo.hpp"
#include "utils.hpp"
#include <getopt.h>
/** @brief Create the data for the burn-in time for temperatures 1.0 and 2.4
* for both unordered and ordered initial states.
* */
@ -43,9 +45,11 @@ void create_pd_estimate_data()
void test_burn_in_time()
{
montecarlo::phase_transition(100, 2.1, 2.4, 40, 1e5, montecarlo::mcmc_serial,
montecarlo::phase_transition(
100, 2.1, 2.4, 40, 1e5, montecarlo::mcmc_serial,
"../output/test_burn_in_time/no_burn_in.txt", 0);
montecarlo::phase_transition(100, 2.1, 2.4, 40, 1e5, montecarlo::mcmc_serial,
montecarlo::phase_transition(
100, 2.1, 2.4, 40, 1e5, montecarlo::mcmc_serial,
"../output/test_burn_in_time/burn_in.txt", 5000);
}
@ -99,18 +103,51 @@ void create_phase_transition_data()
std::cout << "Time: " << t1 - t0 << std::endl;
}
void usage(std::string filename)
{
std::cout << "Usage: " << filename << " OPTION ...\n"
<< "At least one option should be used.\n\n"
<< "\t[ -h | --help ]\n"
<< "\t[ --all ]\n"
<< "\t[ --create-burn-in-data ]\n"
<< "\t[ --create-pd-estimate-data ]\n"
<< "\t[ --create-phase-transition-data ]\n"
<< "\t[ --test-parallel-speedup ]\n"
<< "\t[ --test-burn-in-time ]\n";
exit(-1);
}
/** @brief The main function.*/
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Need at least 1 argument, got " << argc - 1
<< " arguments." << std::endl;
abort();
}
static struct option long_options[] = {
{"all", no_argument, 0, 0},
{"create-burn-in-data", no_argument, 0, 0},
{"create-pd-estimate-data", no_argument, 0, 0},
{"test-parallel-speedup", no_argument, 0, 0},
{"create-phase-transition-data", no_argument, 0, 0},
{"test-burn-in-time", no_argument, 0, 0},
{"help", no_argument, 0, 0}};
int arg = atoi(argv[1]);
int option_index = -1;
int c;
switch (arg) {
while (true) {
c = getopt_long(argc, argv, "h", long_options, &option_index);
if (c == -1)
break;
else if (c == 'h')
usage(argv[0]);
switch (option_index) {
case 0:
create_burn_in_time_data();
create_pd_estimate_data();
test_parallel_speedup();
create_phase_transition_data();
test_burn_in_time();
break;
case 1:
create_burn_in_time_data();
break;
@ -126,9 +163,10 @@ int main(int argc, char **argv)
case 5:
test_burn_in_time();
break;
case 6: // Not a mistake. This just goes to the default.
default:
std::cout << "Not a valid option!" << std::endl;
abort();
usage(argv[0]);
}
}
return 0;

79
src/mcmc_progression.cpp Normal file
View File

@ -0,0 +1,79 @@
/** @file mcmc_progression.cpp
*
* @author Cory Alexander Balaton (coryab)
* @author Janita Ovidie Sandtrøen Willumsen (janitaws)
*
* @version 1.0
*
* @brief Execute the mcmc algorithm and write data to file after each
* Monte Carlo cycle.
*
* @bug No known bugs
* */
#include "data_type.hpp"
#include "monte_carlo.hpp"
#include "utils.hpp"
#include <getopt.h>
#include <omp.h>
#include <string>
void usage(std::string filename)
{
std::cout << "Usage: " << filename
<< " <temperature> <lattice size> "
"<cycles> <burn-in-time> <output file>\n\n"
<< "\t[ -h | --help ]\n";
exit(-1);
}
/** @brief The main function
*
* */
int main(int argc, char **argv)
{
// Command options
struct option long_options[] = {{"help", 0, 0, 0}, {NULL, 0, NULL, 0}};
int option_index = -1;
int c;
while (true) {
c = getopt_long(argc, argv, "h", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
switch (option_index) {
case 0: // Not a mistake. This just goes to the default.
default:
usage(argv[0]);
}
break;
case 'h':
default:
usage(argv[0]);
}
}
// Check that the number of arguments is at least 8.
if (argc < 6) {
usage(argv[0]);
}
// Timing variables
double t0, t1;
t0 = omp_get_wtime();
// Define/initialize variables
double temp = atoi(argv[1]);
int L = atoi(argv[2]), cycles = atoi(argv[3]), burn_in_time = atoi(argv[4]);
std::string outfile = argv[5];
montecarlo::progression(temp, L, cycles, outfile, burn_in_time);
t1 = omp_get_wtime();
std::cout << "Time: " << t1 - t0 << " seconds\n";
}

View File

@ -12,7 +12,8 @@
#include "monte_carlo.hpp"
namespace montecarlo {
void progression(double T, int L, int cycles, const std::string filename)
void progression(double T, int L, int cycles, const std::string filename,
int burn_in_time)
{
// Set some variables
data_t data, tmp;
@ -35,6 +36,10 @@ void progression(double T, int L, int cycles, const std::string filename)
utils::mkpath(directory);
ofile.open(filename);
for (size_t i = 0; i < burn_in_time; i++) {
ising.Metropolis();
}
// Loop through cycles
for (size_t i = 1; i <= cycles; i++) {
data += ising.Metropolis();
@ -46,7 +51,7 @@ void progression(double T, int L, int cycles, const std::string filename)
}
void progression(double T, int L, int cycles, int value,
const std::string filename)
const std::string filename, int burn_in_time)
{
// Set some variables
data_t data, tmp;
@ -65,6 +70,10 @@ void progression(double T, int L, int cycles, int value,
IsingModel ising(L, T, value);
for (size_t i = 0; i < burn_in_time; i++) {
ising.Metropolis();
}
// Create path and open file
utils::mkpath(directory);
ofile.open(filename);
@ -79,7 +88,8 @@ void progression(double T, int L, int cycles, int value,
ofile.close();
}
void pd_estimate(double T, int L, int cycles, const std::string filename)
void pd_estimate(double T, int L, int cycles, const std::string filename,
int burn_in_time)
{
// Set some variables
data_t data, tmp;
@ -91,6 +101,10 @@ void pd_estimate(double T, int L, int cycles, const std::string filename)
IsingModel ising(L, T);
for (size_t i = 0; i < burn_in_time; i++) {
ising.Metropolis();
}
// Create path and open file
utils::mkpath(directory);
ofile.open(filename);

79
src/pd_estimate.cpp Normal file
View File

@ -0,0 +1,79 @@
/** @file pd_estimate.cpp
*
* @author Cory Alexander Balaton (coryab)
* @author Janita Ovidie Sandtrøen Willumsen (janitaws)
*
* @version 1.0
*
* @brief execute the mcmc algorithm and write data to file after each
* Monte Carlo cycles.
*
* @bug No known bugs
* */
#include "data_type.hpp"
#include "monte_carlo.hpp"
#include "utils.hpp"
#include <getopt.h>
#include <omp.h>
#include <string>
void usage(std::string filename)
{
std::cout << "Usage: " << filename
<< " <temperature> <lattice size> "
"<cycles> <burn-in-time> <output file>\n\n"
<< "\t[ -h | --help ]\n";
exit(-1);
}
/** @brief The main function
*
* */
int main(int argc, char **argv)
{
// Command options
struct option long_options[] = {{"help", 0, 0, 0}, {NULL, 0, NULL, 0}};
int option_index = -1;
int c;
while (true) {
c = getopt_long(argc, argv, "h", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
switch (option_index) {
case 0: // Not a mistake. This just goes to the default.
default:
usage(argv[0]);
}
break;
case 'h':
default:
usage(argv[0]);
}
}
// Check that the number of arguments is at least 8.
if (argc < 6) {
usage(argv[0]);
}
// Timing variables
double t0, t1;
t0 = omp_get_wtime();
// Define/initialize variables
double temp = atoi(argv[1]);
int L = atoi(argv[2]), cycles = atoi(argv[3]), burn_in_time = atoi(argv[4]);
std::string outfile = argv[5];
montecarlo::pd_estimate(temp, L, cycles, outfile, burn_in_time);
t1 = omp_get_wtime();
std::cout << "Time: " << t1 - t0 << " seconds\n";
}

84
src/phase_transition.cpp Normal file
View File

@ -0,0 +1,84 @@
/** @file phase_transition.cpp
*
* @author Cory Alexander Balaton (coryab)
* @author Janita Ovidie Sandtrøen Willumsen (janitaws)
*
* @version 1.0
*
* @brief Sweep over different temperatures and generate data.
*
* @details This program takes in 4 arguments: the start temperature,
* the end temperature, the amount of temperature points to simulate, and
* the amount of monte carlo samples to collect, in that order.
*
* @bug No known bugs
* */
#include "data_type.hpp"
#include "monte_carlo.hpp"
#include "utils.hpp"
#include <getopt.h>
#include <omp.h>
#include <string>
void usage(std::string filename)
{
std::cout << "Usage: " << filename
<< " <start temperature> <end temperature> <lattice size> "
"<points> <cycles> <burn-in-time> <output file>\n\n"
<< "\t[ -h | --help ]\n";
exit(-1);
}
/** @brief The main function
*
* */
int main(int argc, char **argv)
{
// Command options
struct option long_options[] = {{"help", 0, 0, 0}, {NULL, 0, NULL, 0}};
int option_index = -1;
int c;
while (true) {
c = getopt_long(argc, argv, "h", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
switch (option_index) {
case 0: // Not a mistake. This just goes to the default.
default:
usage(argv[0]);
}
break;
case 'h':
default:
usage(argv[0]);
}
}
// Check that the number of arguments is at least 8.
if (argc < 8) {
usage(argv[0]);
}
// Timing variables
double t0, t1;
t0 = omp_get_wtime();
// Define/initialize variables
double start = atof(argv[1]), end = atof(argv[2]);
int points = atoi(argv[3]), cycles = atoi(argv[5]), L = atoi(argv[4]),
burn_in_time = atoi(argv[6]), N = L * L;
std::string outfile = argv[7];
montecarlo::phase_transition(L, start, end, points, cycles,
montecarlo::mcmc_parallel, outfile);
t1 = omp_get_wtime();
std::cout << "Time: " << t1 - t0 << " seconds\n";
}

View File

@ -17,17 +17,55 @@
#include "monte_carlo.hpp"
#include "utils.hpp"
#include <getopt.h>
#include <mpi.h>
#include <string>
void usage(std::string filename)
{
std::cout
<< "Usage: " << filename
<< " <start temperature> <end temperature> <lattice size> "
"<points> <cycles> <burn-in-time> <output file>\n"
<< "This should be used with mpiexec or mpirun for maximum "
"performance\n\n"
<< "\t[ -h | --help ]\n";
exit(-1);
}
/** @brief The main function
*
* */
int main(int argc, char **argv)
{
// Check that the number of arguments is at least 4.
if (argc < 7) {
std::cout << "You need at least 6 arguments" << std::endl;
abort();
// Command options
struct option long_options[] = {{"help", 0, 0, 0}, {NULL, 0, NULL, 0}};
int option_index = -1;
int c;
while (true) {
c = getopt_long(argc, argv, "h", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
switch (option_index) {
case 0: // Not a mistake. This just goes to the default.
default:
usage(argv[0]);
}
break;
case 'h':
default:
usage(argv[0]);
}
}
// Check that the number of arguments is at least 8.
if (argc < 8) {
usage(argv[0]);
}
// Timing variables
@ -40,6 +78,7 @@ int main(int argc, char **argv)
burn_in_time = atoi(argv[6]), N = L * L;
double dt = (end - start) / points;
std::ofstream ofile;
std::string outfile = argv[7];
data_t data[points];
// MPI specific variables
@ -100,10 +139,8 @@ int main(int argc, char **argv)
}
// Write everything from data to file
std::stringstream outfile;
outfile << "../output/phase_transition/mpi/size_" << L << ".txt";
utils::mkpath(utils::dirname(outfile.str()));
ofile.open(outfile.str());
utils::mkpath(utils::dirname(outfile));
ofile.open(outfile);
double temp, CV, X;

View File

@ -13,6 +13,7 @@
#include "monte_carlo.hpp"
#include "utils.hpp"
#include <getopt.h>
#include <omp.h>
#include <ostream>
@ -29,8 +30,7 @@ void time_lattice_sizes()
for (int L : lattice_sizes) {
t0 = omp_get_wtime();
montecarlo::phase_transition(L, 2.1, 2.4, 40, 100000,
montecarlo::mcmc_parallel,
"/dev/null");
montecarlo::mcmc_parallel, "/dev/null");
t1 = omp_get_wtime();
ofile << utils::scientific_format(L) << ','
<< utils::scientific_format(t1 - t0) << '\n';
@ -51,8 +51,7 @@ void time_sample_sizes()
for (int samples : sample_sizes) {
t0 = omp_get_wtime();
montecarlo::phase_transition(20, 2.1, 2.4, 40, samples,
montecarlo::mcmc_parallel,
"/dev/null");
montecarlo::mcmc_parallel, "/dev/null");
t1 = omp_get_wtime();
ofile << utils::scientific_format(samples) << ','
<< utils::scientific_format(t1 - t0) << '\n';
@ -60,9 +59,57 @@ void time_sample_sizes()
ofile.close();
}
int main()
void usage(std::string filename)
{
std::cout << "Usage: " << filename << " OPTION ...\n"
<< "At least one option should be used.\n\n"
<< "\t[ -h | --help ]\n"
<< "\t[ --all ]\n"
<< "\t[ --time-lattice-sizes ]\n"
<< "\t[ --time-sample-sizes ]\n";
exit(-1);
}
int main(int argc, char **argv)
{
struct option long_options[] = {{"all", 0, 0, 0},
{"time-lattice-sizes", 0, 0, 0},
{"time-sample-sizes", 0, 0, 0},
{"help", 0, 0, 0},
{NULL, 0, NULL, 0}};
int option_index = -1;
int c;
while (true) {
c = getopt_long(argc, argv, "h", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
switch (option_index) {
case 0:
time_lattice_sizes();
time_sample_sizes();
break;
case 1:
time_lattice_sizes();
break;
case 2:
time_sample_sizes();
break;
case 3: // Not a mistake. This just goes to the default.
default:
usage(argv[0]);
}
break;
case 'h':
default:
usage(argv[0]);
}
}
return 0;
}

View File

@ -60,4 +60,14 @@ std::string dirname(const std::string &path)
return path.substr(0, path.find_last_of("/"));
}
std::string concatpath(const std::string &left, const std::string &right)
{
if (left.back() != '/' and right.front() != '/') {
return left + '/' + right;
}
else {
return left + right;
}
}
} // namespace utils