remove tau loop

This commit is contained in:
Dominik Demuth 2024-08-18 13:21:27 +02:00
parent 17f95627a9
commit 4b2d0da295
12 changed files with 130 additions and 63 deletions

View File

@ -15,6 +15,9 @@ int nearest_index(const std::vector<double> &x_ref, const double x, int start=0)
} }
double lerp(const std::vector<double>& x_ref, const std::vector<double>& y_ref, const double x, const int i) { double lerp(const std::vector<double>& x_ref, const std::vector<double>& y_ref, const double x, const int i) {
/*
* Linear interpolation between two
*/
const double x_left = x_ref[i]; const double x_left = x_ref[i];
const double y_left = y_ref[i]; const double y_left = y_ref[i];
const double x_right = x_ref[i+1]; const double x_right = x_ref[i+1];
@ -26,6 +29,9 @@ double lerp(const std::vector<double>& x_ref, const std::vector<double>& y_ref,
} }
std::chrono::time_point<std::chrono::system_clock> printSteps( std::chrono::time_point<std::chrono::system_clock> printSteps(
/*
* Prints roughly every 10 seconds how many runs were done and gives a time estimation
*/
const std::chrono::time_point<std::chrono::system_clock> last_print_out, const std::chrono::time_point<std::chrono::system_clock> last_print_out,
const std::chrono::time_point<std::chrono::system_clock> start, const std::chrono::time_point<std::chrono::system_clock> start,
const int total, const int total,
@ -37,15 +43,11 @@ std::chrono::time_point<std::chrono::system_clock> printSteps(
return last_print_out; return last_print_out;
} }
std::chrono::duration<float> duration = now - start; const std::chrono::duration<float> duration = now - start;
const auto passed = duration.count(); const auto passed = duration.count();
std::cout << steps << " of " << total << " steps: " << passed << "s passed; ~" << passed * static_cast<float>(total-steps) / static_cast<float>(steps) << "s remaining\n"; std::cout << steps << " of " << total << " steps: " << passed << "s passed; ~" << passed * static_cast<float>(total-steps) / static_cast<float>(steps) << "s remaining\n";
return now; return now;
// time_t end_time = std::chrono::system_clock::to_time_t(end);
// std::cout << "End tau = " << tau_i << "s : " << ctime(&end_time);
// std::cout << "Duration: " << duration.count() << "s\n" << std::endl;
} }

10
io.cpp
View File

@ -12,9 +12,15 @@
#include <unordered_map> #include <unordered_map>
#include <map> #include <map>
#include <string> #include <string>
#include <filesystem>
std::unordered_map<std::string, double> parse_arguments(const char *infile) { std::unordered_map<std::string, double> parse_arguments(const std::filesystem::path& infile) {
if (!std::filesystem::exists(infile)) {
std::cerr << "File " << infile << " does not exist" << std::endl;
exit(1);
}
std::ifstream instream(infile); std::ifstream instream(infile);
std::unordered_map<std::string, double> parameter; std::unordered_map<std::string, double> parameter;
@ -25,8 +31,6 @@ std::unordered_map<std::string, double> parse_arguments(const char *infile) {
std::string value; std::string value;
size_t delim_pos; size_t delim_pos;
// TODO this needs a check for file existence
while (std::getline(instream, line)) { while (std::getline(instream, line)) {
line.erase(std::remove(line.begin(), line.end(), ' '), line.end()); line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
delim_pos = line.find('='); delim_pos = line.find('=');

3
io.h
View File

@ -5,9 +5,10 @@
#include <unordered_map> #include <unordered_map>
#include <map> #include <map>
#include <string> #include <string>
#include <filesystem>
#include <vector> #include <vector>
std::unordered_map<std::string, double> parse_arguments(const char *); std::unordered_map<std::string, double> parse_arguments(const std::filesystem::path&);
void fid_write_out(const std::string&, const std::vector<double>&, const std::vector<double>&, double, double); void fid_write_out(const std::string&, const std::vector<double>&, const std::vector<double>&, double, double);
void fid_write_out(const std::string&, const std::vector<double>&, const std::map<double, std::vector<double>>&, double tau); void fid_write_out(const std::string&, const std::vector<double>&, const std::map<double, std::vector<double>>&, double tau);

View File

@ -1,3 +1,4 @@
#include <iostream>
#include <unordered_map> #include <unordered_map>
#include <random> #include <random>
@ -7,8 +8,15 @@
#include "times/delta.h" #include "times/delta.h"
int main () { int main (int argc, char *argv[]) {
std::unordered_map parameter { parse_arguments("config.txt") };
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " PARAMETER_FILE" << std::endl;
return 1;
}
std::cout << argv[0] << std::endl;
std::unordered_map parameter { parse_arguments(argv[1]) };
std::random_device rd; std::random_device rd;
std::mt19937_64 rng(rd()); std::mt19937_64 rng(rd());

View File

@ -2,11 +2,14 @@
// Created by dominik on 8/12/24. // Created by dominik on 8/12/24.
// //
#include <cmath> // #include <cmath>
#include <random> #include <random>
#include <cmath>
#include <utility>
#include "base.h" #include "base.h"
Motion::Motion(const double delta, const double eta, std::mt19937_64& rng) : m_delta(delta), m_eta(eta), m_rng(rng) { Motion::Motion(const double delta, const double eta, std::mt19937_64& rng) : m_delta(delta), m_eta(eta), m_rng(rng) {
m_uni_dist = std::uniform_real_distribution(0., 1.); m_uni_dist = std::uniform_real_distribution(0., 1.);
} }
@ -19,13 +22,13 @@ double Motion::omega_q(const double cos_theta, const double phi) const {
const double cos_theta_square = cos_theta * cos_theta; const double cos_theta_square = cos_theta * cos_theta;
const double sin_theta_square = 1. - cos_theta_square; const double sin_theta_square = 1. - cos_theta_square;
return M_PI * m_delta * (3 * cos_theta_square - 1 - m_eta * sin_theta_square * cos(2.*phi)); return M_PI * m_delta * (3 * cos_theta_square - 1 - m_eta * sin_theta_square * std::cos(2.*phi));
} }
double Motion::draw_position() { std::pair<double, double> Motion::draw_position() {
const double cos_theta = 1 - 2 * m_uni_dist(m_rng); const double cos_theta = 1 - 2 * m_uni_dist(m_rng);
const double phi = 2.0 * M_PI * m_uni_dist(m_rng); const double phi = 2.0 * M_PI * m_uni_dist(m_rng);
return omega_q(cos_theta, phi); return std::make_pair(cos_theta, phi);
} }

View File

@ -7,6 +7,7 @@
#include <random> #include <random>
#include <utility>
class Motion { class Motion {
public: public:
@ -15,9 +16,10 @@ public:
Motion(double, double, std::mt19937_64&); Motion(double, double, std::mt19937_64&);
explicit Motion(std::mt19937_64&); explicit Motion(std::mt19937_64&);
double draw_position(); std::pair<double, double> draw_position();
[[nodiscard]] double omega_q(double, double) const; [[nodiscard]] double omega_q(double, double) const;
virtual void initialize() = 0;
virtual double jump() = 0; virtual double jump() = 0;
[[nodiscard]] double getDelta() const { return m_delta; } [[nodiscard]] double getDelta() const { return m_delta; }
@ -25,11 +27,11 @@ public:
[[nodiscard]] double getEta() const { return m_eta; } [[nodiscard]] double getEta() const { return m_eta; }
void setEta(const double eta) { m_eta = eta; } void setEta(const double eta) { m_eta = eta; }
private: protected:
double m_delta{1.}; double m_delta{1.};
double m_eta{0.}; double m_eta{0.};
std::mt19937_64& m_rng; std::mt19937_64& m_rng;
std::uniform_real_distribution<double> m_uni_dist; std::uniform_real_distribution<> m_uni_dist;
}; };
#endif //RWSIM_MOTIONBASE_H #endif //RWSIM_MOTIONBASE_H

View File

@ -9,6 +9,9 @@ RandomJump::RandomJump(const double delta, const double eta, std::mt19937_64 &rn
RandomJump::RandomJump(std::mt19937_64 &rng) : Motion(rng) {} RandomJump::RandomJump(std::mt19937_64 &rng) : Motion(rng) {}
void RandomJump::initialize() {}
double RandomJump::jump() { double RandomJump::jump() {
return draw_position(); const auto [cos_theta, phi] = draw_position();
return omega_q(cos_theta, phi);
} }

View File

@ -13,6 +13,7 @@ public:
RandomJump(double, double, std::mt19937_64&); RandomJump(double, double, std::mt19937_64&);
explicit RandomJump(std::mt19937_64&); explicit RandomJump(std::mt19937_64&);
void initialize() override;
double jump() override; double jump() override;
}; };

View File

@ -9,6 +9,46 @@ TetrahedralJump::TetrahedralJump(const double delta, const double eta, std::mt19
TetrahedralJump::TetrahedralJump(std::mt19937_64& rng) : Motion(rng) {} TetrahedralJump::TetrahedralJump(std::mt19937_64& rng) : Motion(rng) {}
double TetrahedralJump::jump() { void TetrahedralJump::initialize() {
return draw_position(); // const auto [cos_theta, phi] = draw_position();
//
// m_corners[0] = omega_q(cos_theta, phi);
//
// const double alpha = 2. * M_PI * m_uni_dist(m_rng);
// std::cout << alpha << std::endl;
// v1[0] = sin(phi0)*sin(teta0);
// v2[0] = cos(phi0)*sin(teta0);
// v3[0] = cos(teta0);
//
// abs = v1[0]*v1[0]+v2[0]*v2[0]+v3[0]*v3[0]; // Normalization
// v1[0] = v1[0]/abs;
// v2[0] = v2[0]/abs;
// v3[0] = v3[0]/abs;
//
// /*Calculating the components of the other orientationts. Compare Master Thesis M. Sattig,corrected Version (Share/Abschlussarbeiten)*/
// norm = sqrt(1 - v3[0]*v3[0])+1E-12;
// normI = 1.0/(norm);
//
// cosgama = cos(delta0);
// singama = sin(delta0);
// v1[1] = v1[0]*cosBETA + sinBETA*normI*(-v1[0]*v3[0]*singama - v2[0]*cosgama);
// v2[1] = v2[0]*cosBETA + sinBETA*normI*(-v2[0]*v3[0]*singama + v1[0]*cosgama);
// v3[1] = v3[0]*cosBETA + sinBETA*norm*singama;
//
// cosgama = cos(gama + delta0);
// singama = sin(gama + delta0);
// v1[2] = v1[0]*cosBETA + sinBETA*normI*(-v1[0]*v3[0]*singama - v2[0]*cosgama);
// v2[2] = v2[0]*cosBETA + sinBETA*normI*(-v2[0]*v3[0]*singama + v1[0]*cosgama);
// v3[2] = v3[0]*cosBETA + sinBETA*norm*singama;
//
// cosgama = cos(2.0*gama + delta0);
// singama = sin(2.0*gama + delta0);
// v1[3] = v1[0]*cosBETA + sinBETA*normI*(-v1[0]*v3[0]*singama - v2[0]*cosgama);
// v2[3] = v2[0]*cosBETA + sinBETA*normI*(-v2[0]*v3[0]*singama + v1[0]*cosgama);
// v3[3] = v3[0]*cosBETA + sinBETA*norm*singama;
}
double TetrahedralJump::jump() {
return 0.;
} }

View File

@ -7,13 +7,20 @@
#include "base.h" #include "base.h"
#include <random> #include <random>
#include <cmath>
#include <array>
class TetrahedralJump final : public Motion { class TetrahedralJump final : public Motion {
public: public:
TetrahedralJump(double, double, std::mt19937_64&); TetrahedralJump(double, double, std::mt19937_64&);
explicit TetrahedralJump(std::mt19937_64&); explicit TetrahedralJump(std::mt19937_64&);
void initialize() override;
double jump() override; double jump() override;
private:
const double m_beta{std::acos(-1/3.)};
std::array<double, 4> m_corners{};
}; };

View File

@ -49,8 +49,8 @@ std::vector<double> logspace(const double start, const double stop, const int st
return range; return range;
} }
const double logstart = log10(start); const double logstart = std::log10(start);
const double logstop = log10(stop); const double logstop = std::log10(stop);
const double stepsize = (logstop-logstart) / (steps-1); const double stepsize = (logstop-logstart) / (steps-1);
for (int i=0; i<steps; i++) { for (int i=0; i<steps; i++) {

View File

@ -73,7 +73,7 @@ void run_spectrum(std::unordered_map<std::string, double>& parameter, Motion& mo
current_pos = nearest_index(traj_time, real_time, current_pos); current_pos = nearest_index(traj_time, real_time, current_pos);
const double phase_acq = lerp(traj_time, traj_phase, real_time, current_pos); const double phase_acq = lerp(traj_time, traj_phase, real_time, current_pos);
fid_j[acq_idx] += cos(phase_acq - 2 * phase_tevo) / num_walker; fid_j[acq_idx] += std::cos(phase_acq - 2 * phase_tevo) / num_walker;
} }
last_print_out = printSteps(last_print_out, start, num_walker, mol_i); last_print_out = printSteps(last_print_out, start, num_walker, mol_i);
} }
@ -95,7 +95,8 @@ void run_ste(std::unordered_map<std::string, double>& parameter, Motion& motion,
const int num_acq = static_cast<int>(parameter[std::string("num_acq")]); const int num_acq = static_cast<int>(parameter[std::string("num_acq")]);
const int num_walker = static_cast<int>(parameter[std::string("num_walker")]); const int num_walker = static_cast<int>(parameter[std::string("num_walker")]);
const std::vector<double> correlation_times = logspace(parameter["tau_start"], parameter["tau_stop"], static_cast<int>(parameter["tau_steps"])); const double tau = parameter["tau"];
dist.setTau(tau);
motion.setDelta(parameter["delta"]); motion.setDelta(parameter["delta"]);
motion.setEta(parameter["eta"]); motion.setEta(parameter["eta"]);
@ -103,7 +104,6 @@ void run_ste(std::unordered_map<std::string, double>& parameter, Motion& motion,
const std::vector<double> evolution_times = linspace(parameter["tevo_start"], parameter["tevo_stop"], static_cast<int>(parameter["tevo_steps"])); const std::vector<double> evolution_times = linspace(parameter["tevo_start"], parameter["tevo_stop"], static_cast<int>(parameter["tevo_steps"]));
const std::vector<double> mixing_times = linspace(parameter["tevo_start"], parameter["tevo_stop"], static_cast<int>(parameter["tevo_steps"])); const std::vector<double> mixing_times = linspace(parameter["tevo_start"], parameter["tevo_stop"], static_cast<int>(parameter["tevo_steps"]));
std::map<double, std::vector<double>> fid_dict; std::map<double, std::vector<double>> fid_dict;
for (auto t_evo_i: evolution_times) { for (auto t_evo_i: evolution_times) {
fid_dict[t_evo_i] = std::vector<double>(num_acq); fid_dict[t_evo_i] = std::vector<double>(num_acq);
@ -111,54 +111,50 @@ void run_ste(std::unordered_map<std::string, double>& parameter, Motion& motion,
} }
// each trajectory must have a duration of at least tmax // each trajectory must have a duration of at least tmax
const double tmax = *std::max_element(evolution_times.begin(), evolution_times.end()) * 2 + *std::max_element(mixing_times.begin(), mixing_times.end()); const double tmax = *std::max_element(evolution_times.begin(), evolution_times.end()) * 2 + *std::max_element(mixing_times.begin(), mixing_times.end());
for (const auto tau_i: correlation_times) { const auto start = std::chrono::system_clock::now();
auto start = std::chrono::system_clock::now(); const time_t start_time = std::chrono::system_clock::to_time_t(start);
time_t start_time = std::chrono::system_clock::to_time_t(start); std::cout << "Start tau = " << tau << "s : " << ctime(&start_time);
std::cout << "Start tau = " << tau_i << "s : " << ctime(&start_time);
dist.setTau(tau_i); for (auto& [_, fid_j]: fid_dict) {
std::fill(fid_j.begin(), fid_j.end(), 0.);
}
for (auto& [_, fid_j]: fid_dict) { // reset array for each correlation time
std::fill(fid_j.begin(), fid_j.end(), 0.); for (int mol_i = 0; mol_i < num_walker; mol_i++){
} std::vector<double> traj_time{};
std::vector<double> traj_phase{};
// reset array for each correlation time make_trajectory(motion, dist, tmax, traj_time, traj_phase);
for (int mol_i = 0; mol_i < num_walker; mol_i++){
std::vector<double> traj_time{};
std::vector<double> traj_phase{};
make_trajectory(motion, dist, tmax, traj_time, traj_phase); for (auto& [t_evo_j, fid_j] : fid_dict) {
int current_pos = nearest_index(traj_time, t_evo_j, 0);
const double phase_tevo = lerp(traj_time, traj_phase, t_evo_j, current_pos);
for (auto& [t_evo_j, fid_j] : fid_dict) { // time axis by echo delay to get time in trajectory
int current_pos = nearest_index(traj_time, t_evo_j, 0);
const double phase_tevo = lerp(traj_time, traj_phase, t_evo_j, current_pos);
// time axis by echo delay to get time in trajectory for (int acq_idx = 0; acq_idx < num_acq; acq_idx++) {
const double real_time = mixing_times[acq_idx] + t_evo_j;
for (int acq_idx = 0; acq_idx < num_acq; acq_idx++) { current_pos = nearest_index(traj_time, real_time, current_pos);
const double real_time = mixing_times[acq_idx] + t_evo_j; const double phase_acq = lerp(traj_time, traj_phase, real_time, current_pos);
current_pos = nearest_index(traj_time, real_time, current_pos); fid_j[acq_idx] += cos(phase_acq - 2 * phase_tevo);
const double phase_acq = lerp(traj_time, traj_phase, real_time, current_pos);
fid_j[acq_idx] += cos(phase_acq - 2 * phase_tevo);
}
} }
} }
// write fid to files
fid_write_out("ste", mixing_times, fid_dict, tau_i);
auto end = std::chrono::system_clock::now();
std::chrono::duration<float> duration = end - start;
time_t end_time = std::chrono::system_clock::to_time_t(end);
std::cout << "End tau = " << tau_i << "s : " << ctime(&end_time);
std::cout << "Duration: " << duration.count() << "s\n" << std::endl;
} }
// write fid to files
fid_write_out("ste", mixing_times, fid_dict, tau);
const auto end = std::chrono::system_clock::now();
const std::chrono::duration<float> duration = end - start;
const time_t end_time = std::chrono::system_clock::to_time_t(end);
std::cout << "End tau = " << tau << "s : " << ctime(&end_time);
std::cout << "Duration: " << duration.count() << "s\n" << std::endl;
} }
@ -167,6 +163,8 @@ void make_trajectory(Motion& motion, const Distribution& dist, const double t_ma
double t_passed = 0; double t_passed = 0;
double phase = 0; double phase = 0;
motion.initialize();
out_time.emplace_back(t_passed); out_time.emplace_back(t_passed);
out_phase.emplace_back(0); out_phase.emplace_back(0);
@ -176,8 +174,6 @@ void make_trajectory(Motion& motion, const Distribution& dist, const double t_ma
phase += motion.jump() * t; phase += motion.jump() * t;
// phase += jump(delta, eta, rng) * t;
out_time.emplace_back(t_passed); out_time.emplace_back(t_passed);
out_phase.emplace_back(phase); out_phase.emplace_back(phase);
} }