8#include "ceres/first_order_function.h"
9#include "ceres/gradient_problem.h"
10#include "ceres/gradient_problem_solver.h"
12#include "highfive/H5File.hpp"
21template <
typename Scalar,
typename Symmetry, Opts::CTMCheckpo
int CPOpts, std::
size_t TRank = 2>
22class Energy final :
public ceres::FirstOrderFunction
24 template <
typename Sym>
31 :
impl(std::move(solver))
39 bool Evaluate(
const double* parameters,
double* cost,
double* gradient)
const override
42 const std::complex<double>* params_compl =
reinterpret_cast<const std::complex<double>*
>(parameters);
43 Psi->set_data(params_compl);
44 std::complex<double>* gradient_compl =
reinterpret_cast<std::complex<double>*
>(gradient);
45 cost[0] =
impl->template solve<Scalar, true>(
Psi, gradient_compl,
op);
47 Psi->set_data(parameters);
48 cost[0] =
impl->template solve<Scalar, true>(
Psi, gradient,
op);
52 std::unique_ptr<CTMSolver<Scalar, Symmetry, CPOpts, TRank>>
impl;
54 std::shared_ptr<iPEPS<Scalar, Symmetry, false>>
Psi;
58template <
typename Scalar,
typename Symmetry, Opts::CTMCheckpoint CPOpts = Opts::CTMCheckpoint{}, std::size_t TRank = 2>
61 template <
typename Sym>
74 constexpr std::size_t flags = yas::file | yas::binary;
80 }
catch(
const std::exception& e) {
81 fmt::print(
"Error while loading file ({}) for resuming simulation.\n",
84 std::cout << std::flush;
92 case Opts::LoadFormat::MATLAB: {
96 case Opts::LoadFormat::NATIVE: {
97 constexpr std::size_t flags = yas::file | yas::binary;
100 yas::load<flags>(load_p.string().c_str(), tmp_Psi);
101 }
catch(
const yas::serialization_exception& se) {
103 "Error while deserializing file ({}) with initial wavefunction.\nThis might be because of incompatible symmetries between this simulation and the loaded wavefunction.",
105 std::cout << std::flush;
107 }
catch(
const yas::io_exception& ie) {
108 fmt::print(
"Error while loading file ({}) with initial wavefunction.\n", load_p.string());
109 std::cout << std::flush;
111 }
catch(
const std::exception& e) {
112 fmt::print(
"Unknown error while loading file ({}) with initial wavefunction.\n", load_p.string());
113 std::cout << std::flush;
116 Psi = std::make_shared<iPEPS<Scalar, Symmetry>>(std::move(tmp_Psi));
120 assert(
Psi->cell().pattern ==
H.data_h.pat);
124 problem = std::make_unique<ceres::GradientProblem>(
132 HighFive::DataSpace dataspace = HighFive::DataSpace({0}, {HighFive::DataSpace::UNLIMITED});
135 HighFive::DataSetCreateProps props;
136 props.add(HighFive::Chunking(std::vector<hsize_t>{10}));
139 if(not file.exist(
"/iteration")) {
140 HighFive::DataSet dataset_i = file.createDataSet(
"/iteration", dataspace, HighFive::create_datatype<int>(), props);
142 if(not file.exist(
"/cost")) {
143 HighFive::DataSet dataset_c = file.createDataSet(
"/cost", dataspace, HighFive::create_datatype<double>(), props);
145 if(not file.exist(
"/grad_norm")) {
146 HighFive::DataSet dataset_g = file.createDataSet(
"/grad_norm", dataspace, HighFive::create_datatype<double>(), props);
148 }
catch(
const std::exception& e) {
149 fmt::print(fg(fmt::color::red),
150 "There already exists a log file for this simulation:{}.\n",
153 std::cout << std::flush;
159 if(std::filesystem::exists(
165 if(file.exist(fmt::format(
"/{}/{}",
Psi->D, ctm_opts.
chi))) {
166 fmt::print(fg(fmt::color::red),
167 "There already exists data in observable file for D={}, chi={}.\n Filename:{}.\n",
172 std::cout << std::flush;
180 }
catch(
const std::exception& e) {
181 fmt::print(fg(fmt::color::red),
182 "Error while creating the observable file for this simulation:{}.\n",
185 std::cout << std::flush;
193 template <
typename HamScalar>
197 "{}: Model={}(Bonds: V:{}, H:{}, D1: {}, D2: {})",
198 fmt::styled(
"iPEPSSolverAD", fmt::emphasis::bold),
211 std::vector<Scalar> parameters =
Psi->data();
216 case Opts::Algorithm::L_BFGS:
options.line_search_direction_type = ceres::LBFGS;
break;
217 case Opts::Algorithm::CONJUGATE_GRADIENT:
options.line_search_direction_type = ceres::NONLINEAR_CONJUGATE_GRADIENT;
break;
218 case Opts::Algorithm::NELDER_MEAD:
throw std::invalid_argument(
"Nelder-Mead optimization is not in ceres.");
222 case Opts::Linesearch::WOLFE:
options.line_search_type = ceres::WOLFE;
break;
223 case Opts::Linesearch::ARMIJO:
options.line_search_type = ceres::ARMIJO;
break;
225 options.logging_type = ceres::SILENT;
226 options.minimizer_progress_to_stdout =
true;
233 options.update_state_every_iteration =
true;
235 options.callbacks.push_back(&get_state_c);
237 options.callbacks.push_back(&logging_c);
239 options.callbacks.push_back(&obs_c);
241 options.callbacks.push_back(&custom_c);
244 ceres::GradientProblemSolver::Summary summary;
251 custom_c((summary.iterations.size() > 0) ? summary.iterations.back() : ceres::IterationSummary{});
252 obs_c((summary.iterations.size() > 0) ? summary.iterations.back() : ceres::IterationSummary{});
262 template <
typename Ar>
280 ceres::GradientProblemSolver::Options
options;
282 std::shared_ptr<iPEPS<Scalar, Symmetry>>
Psi;
283 std::unique_ptr<ceres::GradientProblem>
problem;
285 template <
typename Ar>
288 ar& YAS_OBJECT_NVP(
"iPEPSSolverAD",
295 template <
typename Ar>
300 ar& YAS_OBJECT_NVP(
"iPEPSSolverAD", (
"CTMSolver", tmp_CTMSolver), (
"Psi", tmp_Psi), (
"optim_opts",
optim_opts), (
"state",
state));
302 Psi = std::make_shared<iPEPS<Scalar, Symmetry>>(std::move(tmp_Psi));
303 auto Dwain = std::make_unique<CTMSolver<Scalar, Symmetry, CPOpts, TRank>>(std::move(tmp_CTMSolver));
314 ceres::CallbackReturnType
operator()(
const ceres::IterationSummary& summary)
317 return ceres::SOLVER_CONTINUE;
330 ceres::CallbackReturnType
operator()(
const ceres::IterationSummary& summary)
336 return ceres::SOLVER_CONTINUE;
347 ceres::CallbackReturnType
operator()(
const ceres::IterationSummary& summary)
350 "{}{:^4d}: E={:+.8f}, ΔE={:.1e}, |∇|={:.1e}, step time={}, total time={}",
351 fmt::styled(
"Iteration=", fmt::emphasis::bold),
352 fmt::styled(summary.iteration, fmt::emphasis::bold),
355 summary.gradient_norm,
356 util::format_secs(std::chrono::duration<
double, std::ratio<1, 1>>(summary.iteration_time_in_seconds)),
357 util::format_secs(std::chrono::duration<
double, std::ratio<1, 1>>(summary.cumulative_time_in_seconds)));
361 fmt::format(
"_D={}_chi={}_seed={}_id={}.h5",
366 HighFive::File::OpenOrCreate);
367 auto insert_elem = [&file](
const std::string& name,
auto elem) {
368 auto d = file.getDataSet(name);
369 std::size_t curr_size = d.getElementCount();
370 d.resize({curr_size + 1});
371 decltype(elem) elem_a[1] = {elem};
372 d.select({curr_size}, {1}).write(elem_a);
374 insert_elem(
"/iteration", summary.iteration);
375 insert_elem(
"/cost", summary.cost);
376 insert_elem(
"/grad_norm", summary.gradient_norm);
379 fmt::format(
"_D={}_chi={}_seed={}_id={}{}",
386 ofs << summary.iteration <<
'\t' << summary.cost <<
'\t' << summary.gradient_norm << std::endl;
389 return ceres::SOLVER_CONTINUE;
400 ceres::CallbackReturnType
operator()(
const ceres::IterationSummary& summary)
409 HighFive::File::OpenOrCreate);
411 if(not file.exist(e_name)) {
412 HighFive::DataSpace dataspace = HighFive::DataSpace({0, 0}, {HighFive::DataSpace::UNLIMITED, HighFive::DataSpace::UNLIMITED});
415 HighFive::DataSetCreateProps props;
416 props.add(HighFive::Chunking(std::vector<hsize_t>{2, 2}));
419 HighFive::DataSet dataset = file.createDataSet(e_name, dataspace, HighFive::create_datatype<double>(), props);
422 auto d = file.getDataSet(e_name);
423 std::vector<std::vector<double>> data;
424 data.push_back(std::vector<double>(1, summary.cost));
425 std::size_t curr_size = d.getDimensions()[0];
426 d.resize({curr_size + 1, data[0].size()});
427 d.select({curr_size, 0}, {1, data[0].size()}).write(data);
430 if(not file.exist(g_name)) {
431 HighFive::DataSpace dataspace = HighFive::DataSpace({0, 0}, {HighFive::DataSpace::UNLIMITED, HighFive::DataSpace::UNLIMITED});
434 HighFive::DataSetCreateProps props;
435 props.add(HighFive::Chunking(std::vector<hsize_t>{2, 2}));
438 HighFive::DataSet dataset = file.createDataSet(g_name, dataspace, HighFive::create_datatype<double>(), props);
441 auto d = file.getDataSet(g_name);
442 std::vector<std::vector<double>> data;
443 data.push_back(std::vector<double>(1, summary.gradient_norm));
444 std::size_t curr_size = d.getDimensions()[0];
445 d.resize({curr_size + 1, data[0].size()});
446 d.select({curr_size, 0}, {1, data[0].size()}).write(data);
450 return ceres::SOLVER_CONTINUE;
461 ceres::CallbackReturnType
operator()(
const ceres::IterationSummary& summary)
464 if(summary.iteration == 0) {
return ceres::SOLVER_CONTINUE; }
466 constexpr std::size_t flags = yas::file | yas::binary;
468 fmt::format(
"_D={}_chi={}_seed={}_id={}.ad",
475 yas::save<flags>(ofs_ad,
solver);
477 fmt::format(
"_D={}_chi={}_seed={}_id={}.psi",
486 return ceres::SOLVER_CONTINUE;
Definition: CTMSolver.hpp:18
Definition: CeresSolve.hpp:23
bool Evaluate(const double *parameters, double *cost, double *gradient) const override
Definition: CeresSolve.hpp:39
int NumParameters() const override
Definition: CeresSolve.hpp:55
~Energy() override
Definition: CeresSolve.hpp:37
Hamiltonian< Symmetry > & op
Definition: CeresSolve.hpp:53
std::unique_ptr< CTMSolver< Scalar, Symmetry, CPOpts, TRank > > impl
Definition: CeresSolve.hpp:52
std::shared_ptr< iPEPS< Scalar, Symmetry, false > > Psi
Definition: CeresSolve.hpp:54
Energy(std::unique_ptr< CTMSolver< Scalar, Symmetry, CPOpts, TRank > > solver, Hamiltonian< Symmetry > &op, std::shared_ptr< iPEPS< Scalar, Symmetry, false > > Psi)
Definition: CeresSolve.hpp:28
constexpr void on_exit(Verbosity policy, Args &&... args)
Definition: Logging.hpp:102
constexpr void on_entry(Verbosity policy, Args &&... args)
Definition: Logging.hpp:108
constexpr void per_iteration(Verbosity policy, Args &&... args)
Definition: Logging.hpp:114
std::string format_secs(std::chrono::duration< double, std::ratio< 1, 1 > > dts)
Definition: Stopwatch.hpp:25
Definition: CTMOpts.hpp:28
std::size_t chi
Definition: CTMOpts.hpp:29
Definition: OptimOpts.hpp:25
Linesearch ls
Definition: OptimOpts.hpp:28
std::size_t seed
Definition: OptimOpts.hpp:46
bool resume
Definition: OptimOpts.hpp:40
Algorithm alg
Definition: OptimOpts.hpp:26
LoadFormat load_format
Definition: OptimOpts.hpp:42
std::filesystem::path logging_directory
Definition: OptimOpts.hpp:55
bool display_obs
Definition: OptimOpts.hpp:58
double grad_tol
Definition: OptimOpts.hpp:33
std::size_t id
Definition: OptimOpts.hpp:48
auto info()
Definition: OptimOpts.hpp:88
bool bfgs_scaling
Definition: OptimOpts.hpp:31
Verbosity verbosity
Definition: OptimOpts.hpp:60
std::size_t max_steps
Definition: OptimOpts.hpp:37
std::string log_format
Definition: OptimOpts.hpp:52
int qn_scale
Definition: OptimOpts.hpp:44
std::string load
Definition: OptimOpts.hpp:43
std::size_t save_period
Definition: OptimOpts.hpp:50
std::filesystem::path working_directory
Definition: OptimOpts.hpp:54
std::filesystem::path obs_directory
Definition: OptimOpts.hpp:57
double step_tol
Definition: OptimOpts.hpp:34
double cost_tol
Definition: OptimOpts.hpp:35
Definition: ScalarTraits.hpp:10
Definition: TwoSiteObservable.hpp:22
Definition: CeresSolve.hpp:308
ceres::CallbackReturnType operator()(const ceres::IterationSummary &summary)
Definition: CeresSolve.hpp:314
XPED_CONST CTM< Scalar, Symmetry, TRank > & c
Definition: CeresSolve.hpp:321
CustomCallback(const iPEPSSolverAD &s, XPED_CONST CTM< Scalar, Symmetry, TRank > &c)
Definition: CeresSolve.hpp:309
const iPEPSSolverAD & s
Definition: CeresSolve.hpp:320
Definition: CeresSolve.hpp:325
SolverState & state
Definition: CeresSolve.hpp:338
ceres::CallbackReturnType operator()(const ceres::IterationSummary &summary)
Definition: CeresSolve.hpp:330
GetStateCallback(SolverState &state_in)
Definition: CeresSolve.hpp:326
Definition: CeresSolve.hpp:342
LoggingCallback(const iPEPSSolverAD &solver_in)
Definition: CeresSolve.hpp:343
ceres::CallbackReturnType operator()(const ceres::IterationSummary &summary)
Definition: CeresSolve.hpp:347
const iPEPSSolverAD & solver
Definition: CeresSolve.hpp:391
Definition: CeresSolve.hpp:395
ceres::CallbackReturnType operator()(const ceres::IterationSummary &summary)
Definition: CeresSolve.hpp:400
iPEPSSolverAD & solver
Definition: CeresSolve.hpp:452
ObsCallback(iPEPSSolverAD &solver_in)
Definition: CeresSolve.hpp:396
Definition: CeresSolve.hpp:456
const iPEPSSolverAD & solver
Definition: CeresSolve.hpp:488
ceres::CallbackReturnType operator()(const ceres::IterationSummary &summary)
Definition: CeresSolve.hpp:461
SaveCallback(const iPEPSSolverAD &solver_in)
Definition: CeresSolve.hpp:457
Definition: CeresSolve.hpp:257
double cost
Definition: CeresSolve.hpp:260
double grad_norm
Definition: CeresSolve.hpp:259
std::size_t current_iter
Definition: CeresSolve.hpp:258
void serialize(Ar &ar)
Definition: CeresSolve.hpp:263
double step_norm
Definition: CeresSolve.hpp:261
Definition: CeresSolve.hpp:60
Hamiltonian< Symmetry > & H
Definition: CeresSolve.hpp:281
CTMSolver< Scalar, Symmetry, CPOpts, TRank > * getCTMSolver()
Definition: CeresSolve.hpp:269
SolverState state
Definition: CeresSolve.hpp:278
void serialize(Ar &ar) const
Definition: CeresSolve.hpp:286
std::unique_ptr< ceres::GradientProblem > problem
Definition: CeresSolve.hpp:283
ceres::GradientProblemSolver::Options options
Definition: CeresSolve.hpp:280
void solve()
Definition: CeresSolve.hpp:194
iPEPSSolverAD(Opts::Optim optim_opts, Opts::CTM ctm_opts, std::shared_ptr< iPEPS< Scalar, Symmetry > > Psi_in, Hamiltonian< Symmetry > &H_in)
Definition: CeresSolve.hpp:67
std::shared_ptr< iPEPS< Scalar, Symmetry > > Psi
Definition: CeresSolve.hpp:282
std::function< void(XPED_CONST CTM< Scalar, Symmetry, TRank > &ctm, std::size_t)> callback
Definition: CeresSolve.hpp:276
Opts::Optim optim_opts
Definition: CeresSolve.hpp:275
void serialize(Ar &ar)
Definition: CeresSolve.hpp:296
Energy< Scalar, Symmetry, CPOpts, TRank > EnergyFunctor
Definition: CeresSolve.hpp:63
const CTMSolver< Scalar, Symmetry, CPOpts, TRank > * getCTMSolver() const
Definition: CeresSolve.hpp:270