This commit is contained in:
matthias@quintern.xyz 2025-03-23 20:39:11 +01:00
parent 6289314557
commit de2269e650
6 changed files with 99 additions and 90 deletions

1
.gitignore vendored
View File

@ -14,4 +14,3 @@ src/.old
src/pch.hpp.gch
test-python/
web/

View File

@ -149,7 +149,7 @@ void testTFI_TEBD() {
// });
std::println("E = {}", model.energy(psi).real());
std::println("m = {}", psi.getSiteExpectationValues(sigma_z));
std::println("chiS: {:b}", psi.getChi());
std::println("chiS: {}", psi.getChi());
psi.print();
std::println("<psi|psi>={}", psi.collapse(0));
@ -166,7 +166,7 @@ void testTFI_TEBD() {
std::println("E = {}", model.energy(psi).real());
std::println("m = {}", psi.getSiteExpectationValues(sigma_z));
std::println("chiS: {:b}", psi.getChi());
std::println("chiS: {}", psi.getChi());
// psi.print();
std::println("<psi|psi>={}", psi.collapse(0));

View File

@ -9,6 +9,8 @@ PauliMatrices<T> TransverseFieldIsingModel1D<T>::pm;
template<typename T>
void TransverseFieldIsingModel1D<T>::initH_Bonds() {
T BHalf = this->B * static_cast<T>(0.5);
///@todo TODO remove this after testing!
// T BHalf = this->B;
// TODO: improve code or directly initialize the tensors
auto left = std::make_shared<e::MatrixX<T>>(
e::kroneckerProduct(pm.getSigmaZ(), pm.getSigmaZ()) * (-J)

View File

@ -7,87 +7,104 @@
#include "type.hpp"
template<typename U>
struct std::formatter<std::vector<U>> {
using T = std::vector<U>;
// using std::formatter<int>::parse;
constexpr auto parse(std::format_parse_context& ctx){
auto pos = ctx.begin();
while (pos != ctx.end() && *pos != '}') {
if (*pos == 'a') { useChar = 1; }
else if (*pos == 'b') { useChar = 2; }
else if (*pos == 'p') { useChar = 3; }
++pos;
}
return pos; // expect `}` at this position, otherwise its an error
}
auto format(const T& v, auto& ctx) const {
// TODO figure out why tf it doesnt compile with openChars.at(..)
auto out = ctx.out();
// out = std::format_to(out, "{}", openChars.at(useChar));
char c = '{';
if (useChar > 0) { c = '<'; }
out = std::format_to(out, "{}", c);
auto it = v.begin();
if (it != v.end()) {
out = std::format_to(out, "{}", *it);
}
it++;
for (; it != v.end(); it++) {
out = std::format_to(out, ", {}", *it);
}
// return std::format_to(out, "{}", closeChars.at(useChar));
c = '}';
if (useChar > 0) { c = '>'; }
return std::format_to(out, "{}", c);
// return out;
}
public:
size_t useChar = 0;
static constexpr std::string openChars{"(<[{"};
static constexpr std::string closeChars{")>]}"};
};
// FORMATING
template<typename T, class CharT=char>
concept FormatableRange = std::ranges::forward_range<T> && std::formattable<std::ranges::range_value_t<T>, CharT>;
/**
* @brief Format ranges
* @details
* Format string accepts c = {curly brackets}, b = [box brackets], a = <angle brackets>, r = (round brackets)
* @note With some clang lib update, this became obsolete!
*/
/*template<typename U, class CharT> requires FormatableRange<U, CharT>*/
/*struct std::formatter<U, CharT> {*/
/* using T = std::ranges::range_value_t<U>;*/
/* constexpr auto parse(std::format_parse_context& ctx){*/
/* auto pos = ctx.begin();*/
/* while (pos != ctx.end() && *pos != '}') {*/
/* if (*pos == 'a') { useChar = 0; } // <a>ngle*/
/* else if (*pos == 'b') { useChar = 1; } // [b]ox*/
/* else if (*pos == 'c') { useChar = 2; } // {c}urly*/
/* else if (*pos == 'p') { useChar = 3; } // (r)ound*/
/* else {*/
/* throw std::format_error("Invalid format args for forward range.");*/
/* }*/
/* ++pos;*/
/* }*/
/* return pos; // expect `}` at this position, otherwise its an error*/
/* }*/
/* auto format(const U& v, auto& ctx) const {*/
/* auto out = ctx.out();*/
/* char c = openChars.at(useChar);*/
/* out = std::format_to(out, "{}", c);*/
/**/
/* auto it = v.begin();*/
/* if (it != v.end()) {*/
/* out = std::format_to(out, "{}", *it);*/
/* }*/
/* it++;*/
/* for (; it != v.end(); it++) {*/
/* out = std::format_to(out, ", {}", *it);*/
/* }*/
/* c = closeChars.at(useChar);*/
/* return std::format_to(out, "{}", c);*/
/* // return out;*/
/* }*/
/* public:*/
/* size_t useChar = 2; */
/* static constexpr std::string_view openChars = "<[{()";*/
/* static constexpr std::string_view closeChars{">]})"};*/
/*};*/
/**
* @brief Format complex numbers
*/
template<typename U>
struct std::formatter<std::complex<U>> : std::formatter<U> {
using T = std::complex<U>;
// use default formater for the value type
using std::formatter<U>::parse;
/*constexpr auto parse(std::format_parse_context& ctx){*/
/* auto pos = ctx.begin();*/
/* while (pos != ctx.end() && *pos != '}') {*/
/* if (*pos == 'i') { useImag = true; }*/
/* ++pos;*/
/* }*/
/* return pos;*/
/*}*/
auto format(const T& v, auto& ctx) const {
auto out = ctx.out();
out = std::format_to(out, "({}, {})", v.real(), v.imag());
if (useImag) {
out = std::format_to(out, "{}+{}i", v.real(), v.imag());
}
else {
out = std::format_to(out, "({}, {})", v.real(), v.imag());
}
return out;
}
bool useImag = false;
};
// Make every class with public std::string format() const member formatable
template <typename T>
concept HasFormat = requires(const T obj) {
{ obj.format() } -> std::convertible_to<std::string>;
};
template<HasFormat T>
struct std::formatter<T> {
constexpr auto parse(std::format_parse_context& ctx) {
return ctx.begin();
}
auto format(const T& obj, auto& ctx) const {
return std::format_to(ctx.out(), "{}", obj.format());
}
};
// // Formatter specialization for std::complex
// template <typename T>
// struct std::formatter<std::complex<T>> {
// std::formatter<char> inner_formatter; // Inner formatter for real/imaginary parts
// // Parse the format specifier
// constexpr auto parse(std::format_parse_context& ctx) {
// // Use the same format specifier for real/imaginary parts as for other types
// return inner_formatter.parse(ctx);
// }
// // Format the complex number
// template <typename FormatContext>
// auto format(const std::complex<T>& c, FormatContext& ctx) {
// // Format both real and imaginary parts using the inner formatter
// return std::format_to(
// ctx.out(),
// "({} + {}i)",
// std::format(inner_formatter, c.real()), // Format real part
// std::format(inner_formatter, c.imag()) // Format imaginary part
// );
// }
// };
// OTHER
template<typename T, typename string_type>
void printTensor(const T& t, string_type name="") {
std::cout << name << "(" << t.dimensions() << ") = \n" << t << "\n" << std::endl;
@ -116,17 +133,3 @@ void throwIfLessThan(const T& v, const T& compare, std::string_view name) {
}
}
// Make every class with public std::string format() const member formatable
template <typename T>
concept HasFormat = requires(const T obj) {
{ obj.format() } -> std::convertible_to<std::string>;
};
template<HasFormat T>
struct std::formatter<T> {
constexpr auto parse(std::format_parse_context& ctx) {
return ctx.begin();
}
auto format(const T& obj, auto& ctx) const {
return std::format_to(ctx.out(), "{}", obj.format());
}
};

View File

@ -22,7 +22,6 @@ class Results {
virtual void finalize(std::shared_ptr<Model> model, const MPS<dtype>& psi) = 0;
/// Norm of the MPS
dtype finalNorm = 0;
std::vector<dtype> finalStates;
};
@ -31,7 +30,7 @@ class TfiResults : public Results<TfiModel> {
using Model_t = TfiModel;
TfiResults(ems::val callback, double convergence) : callback(callback), convergence(convergence), previousE(std::numeric_limits<double>::max()) {
sigmaZ.setValues({{1, 0}, {0, -1}});
// sigmaZ.setValues({{0, 1}, {1, 0}});
sigmaX.setValues({{0, 1}, {1, 0}});
};
/// @todo write a second postUpdateFunction without the JS callback and return that one if callback is null
postUpdateFunction_t<dtype> getPostUpdateFunction(std::shared_ptr<TfiModel> model) override {
@ -51,10 +50,14 @@ class TfiResults : public Results<TfiModel> {
}
void finalize(std::shared_ptr<TfiModel> model, const MPS<dtype>& psi) override {
this->finalNorm = psi.collapse(0);
this->finalStates = psi.getSiteExpectationValues(this->sigmaZ);
this->finalStatesZ = psi.getSiteExpectationValues(this->sigmaZ);
this->finalStatesX = psi.getSiteExpectationValues(this->sigmaX);
}
std::vector<dtype> finalStatesZ;
std::vector<dtype> finalStatesX;
private:
e::TensorFixedSize<dtype, e::Sizes<2, 2>> sigmaZ;
e::TensorFixedSize<dtype, e::Sizes<2, 2>> sigmaX;
ems::val callback;
double convergence;
double previousE;
@ -86,8 +89,9 @@ class BoseHubbardResults : public Results<BhModel> {
void finalize(std::shared_ptr<BhModel> model, const MPS<dtype>& psi) override {
e::TensorMap<const e::Tensor<dtype, 2>> particleNumberOperator(model->getLadderOperators().getN().data(), model->localDim, model->localDim);
this->finalNorm = psi.collapse(0);
this->finalStates = psi.getSiteExpectationValues(particleNumberOperator);
this->finalStatesN = psi.getSiteExpectationValues(particleNumberOperator);
}
std::vector<dtype> finalStatesN;
private:
ems::val callback;
double convergence;

View File

@ -50,17 +50,18 @@ EMSCRIPTEN_BINDINGS(run) {
// RESULTS
ems::class_<Results<TfiModel>>("ResultsBaseTfi")
.property("finalNorm", &Results<TfiModel>::finalNorm)
.property("finalStates", &Results<TfiModel>::finalStates, ems::return_value_policy::reference())
;
ems::class_<Results<BhModel>>("ResultsBaseBh")
.property("finalNorm", &Results<BhModel>::finalNorm)
.property("finalStates", &Results<BhModel>::finalStates, ems::return_value_policy::reference())
;
ems::class_<TfiResults, ems::base<Results<TfiModel>>>("ResultsTfi")
.constructor<ems::val, double>()
.property("finalStatesX", &TfiResults::finalStatesX, ems::return_value_policy::reference())
.property("finalStatesZ", &TfiResults::finalStatesZ, ems::return_value_policy::reference())
;
ems::class_<BoseHubbardResults, ems::base<Results<BhModel>>>("ResultsBh")
.constructor<ems::val, double>()
.property("finalStatesN", &BoseHubbardResults::finalStatesN, ems::return_value_policy::reference())
;
// MODELS
ems::class_<Model1D<dtype>>("Model1D")