sisi4s
Loading...
Searching...
No Matches
FockVector.hpp
Go to the documentation of this file.
1#ifndef FOCK_VECTOR_DEFINED
2#define FOCK_VECTOR_DEFINED
3
7#include <util/Exception.hpp>
9#include <Sisi4s.hpp>
10
11#include <vector>
12#include <string>
13#include <algorithm>
14#include <ostream>
15
16#include <util/Tensor.hpp>
17
18namespace sisi4s {
19template <typename F = double>
27public:
28 typedef F FieldType;
29
31 std::vector<std::string> component_indices;
32
37
44 , index_ends(a.component_tensors.size()) {
46 }
47
54 , index_ends(a.component_tensors.size()) {
57 }
58
62 FockVector(const std::vector<PTR(Tensor<F>)> &tensors,
63 const std::vector<std::string> &indices)
64 : component_tensors(tensors)
65 , component_indices(indices)
68 }
69
74 template <typename TensorsIterator, typename IndicesIterator>
75 FockVector(TensorsIterator tensorsBegin,
76 TensorsIterator tensorsEnd,
77 IndicesIterator indicesBegin,
78 IndicesIterator indicesEnd)
79 : component_tensors(tensorsBegin, tensorsEnd)
80 , component_indices(indicesBegin, indicesEnd)
83 }
84
90 const PTR(Tensor<F>) &get(const size_t i) const {
91 return component_tensors[i];
92 }
93
97 PTR(Tensor<F>) &get(const size_t i) { return component_tensors[i]; }
98
102 const std::string &get_indices(const size_t i) const {
103 return component_indices[i];
104 }
105
109 std::string &get_indices(const size_t i) { return component_indices[i]; }
110
116 component_tensors = a.component_tensors;
117 component_indices = a.component_indices;
119 return *this;
120 }
121
129 return *this;
130 }
131
138 for (size_t i(0); i < component_tensors.size(); ++i) {
139 const char *indices(component_indices[i].c_str());
140 get(i)->sum(+1.0, *a.get(i), indices, 1.0, indices);
141 }
142 return *this;
143 }
144
151 for (size_t i(0); i < component_tensors.size(); ++i) {
152 const char *indices(get_indices(i).c_str());
153 get(i)->sum(-1.0, *a.get(i), indices, 1.0, indices);
154 }
155 return *this;
156 }
157
163 for (size_t i(0); i < component_tensors.size(); ++i) {
164 const char *indices(get_indices(i).c_str());
165 get(i)->sum(s, *get(i), indices, 0.0, indices);
166 }
167 return *this;
168 }
169
177 FockVector<F> result;
178 for (size_t i(0); i < component_tensors.size(); ++i) {
179 size_t order(get_indices(i).length() / 2);
180 std::vector<int> transposedLens(get(i)->lens, get(i)->lens + 2 * order);
181 std::rotate(transposedLens.begin(),
182 transposedLens.begin() + order,
183 transposedLens.begin() + 2 * order);
184 result.component_tensors.push_back(
186 transposedLens.size(),
187 transposedLens.data(),
188 get(i)->sym,
189 *get(i)->wrld,
190 (std::string(get(i)->get_name()) + "*").c_str()));
191 result.component_indices.push_back(get_indices(i).substr(order, 2 * order)
192 + get_indices(i).substr(0, order));
193 CTF::Univar_Function<F> fConj(sisi4s::conj<F>);
194 result.get(i)->sum(1.0,
195 *get(i),
196 get_indices(i).c_str(),
197 0.0,
198 result.get_indices(i).c_str(),
199 fConj);
200 }
201 return result;
202 }
203
208 F braket(const FockVector<F> &ket) const {
209 // checkDualCompatibility(ket);
210 CTF::Scalar<F> result;
211 for (size_t i(0); i < component_tensors.size(); ++i) {
212 const char *indices(get_indices(i).c_str());
213 const char *ketIndices(ket.get_indices(i).c_str());
214 // add to result
215 result[""] += (*get(i))[indices] * (*ket.get(i))[ketIndices];
216 }
217 return result.get_val();
218 }
219
226 F dot(const FockVector<F> &a) const {
228 CTF::Scalar<F> result;
229 for (size_t i(0); i < component_tensors.size(); ++i) {
230 const char *indices(get_indices(i).c_str());
231 CTF::Bivar_Function<F> fDot(&sisi4s::dot<F>);
232 // add to result
233 result.contract(1.0, *get(i), indices, *a.get(i), indices, 1.0, "", fDot);
234 }
235 return result.get_val();
236 }
237
241 size_t get_components_count() const { return component_tensors.size(); }
242
249 size_t get_dimension() const { return index_ends.back(); }
250
255 size_t get_index(const size_t component, const size_t componentIndex) const {
256 size_t base(component > 0 ? index_ends[component - 1] : 0);
257 return base + componentIndex;
258 }
259
265 void fromIndex(const size_t index,
266 size_t &component,
267 size_t &componentIndex) const {
268 component = 0;
269 size_t base(0);
270 while (component < index_ends.size()) {
271 if (index < index_ends[component]) break;
272 base = index_ends[component++];
273 }
274 if (component >= index_ends.size()) {
275 throw new EXCEPTION("Index out bounds");
276 }
277 componentIndex = index - base;
278 }
279
284 std::vector<std::pair<size_t, F>> readLocal() const {
285 size_t elementsCount(0);
286 std::vector<std::pair<size_t, F>> elements;
287 for (size_t i(0); i < component_tensors.size(); ++i) {
288 size_t componentValuesCount;
289 size_t *component_indices;
290 F *componentValues;
291 get(i)->read_local(reinterpret_cast<int64_t *>(&componentValuesCount),
292 reinterpret_cast<int64_t **>(&component_indices),
293 &componentValues);
294
295 elements.resize(elementsCount + componentValuesCount);
296 for (size_t k(0); k < componentValuesCount; ++k) {
297 // translate index within component tensor to FockVector index
298 elements[elementsCount + k].first = get_index(i, component_indices[k]);
299 elements[elementsCount + k].second = componentValues[k];
300 }
301 elementsCount += componentValuesCount;
302 free(component_indices);
303 free(componentValues);
304 }
305 return elements;
306 }
307
312 void write(const std::vector<std::pair<size_t, F>> &elements) {
313 // vectors to contain indices and values for each component tensor
314 std::vector<std::vector<size_t>> tensorIndices(component_tensors.size());
315 std::vector<std::vector<F>> tensorValues(component_tensors.size());
316
317 for (size_t k(0); k < elements.size(); ++k) {
318 size_t component;
319 size_t componentIndex;
320 fromIndex(elements[k].first, component, componentIndex);
321 // write to respective component tensor
322 tensorIndices[component].push_back(componentIndex);
323 tensorValues[component].push_back(elements[k].second);
324 }
325
326 // write data of each tensor
327 for (size_t i(0); i < component_tensors.size(); ++i) {
328 tensorIndices[i].reserve(tensorIndices[i].size() + 1);
329 tensorValues[i].reserve(tensorIndices[i].size() + 1);
330 get(i)->write(tensorIndices[i].size(),
331 reinterpret_cast<int64_t *>(tensorIndices[i].data()),
332 tensorValues[i].data());
333 }
334 }
335
336protected:
342 std::vector<size_t> index_ends;
343
349 index_ends.resize(component_tensors.size());
350 size_t indexBase(0);
351 for (size_t i(0); i < component_tensors.size(); ++i) {
352 size_t tensorIndexSize(1);
353 for (int d(0); d < get(i)->order; ++d) {
354 tensorIndexSize *= get(i)->lens[d];
355 }
356 index_ends[i] = indexBase += tensorIndexSize;
357 }
358 }
359
364 void copy_components(const std::vector<PTR(Tensor<F>)> &components) {
365 component_tensors.resize(components.size());
366 for (size_t i(0); i < components.size(); ++i) {
367 component_tensors[i] = NEW(Tensor<F>, *components[i]);
368 }
369 }
370
375 // TODO: Improve speed?
378 for (size_t i(0); i < component_tensors.size(); i++) {
379 size_t indexLens(a.get(i)->order());
380 for (size_t j(0); j < indexLens; j++) {
381 size_t indexPos(get(i).find(a.getIndicies(i)[j]));
382 if (indexPos == std::string::npos) {
383 throw EXCEPTION("Indices of fock vectors do not match");
384 }
385 if (a.get(i)->lens[j] != get(i)->lens[indexPos]) {
386 throw EXCEPTION("Shapes of component tensors does not match");
387 }
388 }
389 }
390 }
391
392 void checkCompatibilityTo(const FockVector<F> &a) const {
393 if (component_tensors.size() != a.component_tensors.size()
394 || component_indices.size() != a.component_indices.size()) {
395 throw EXCEPTION("Number of component tensors does no match");
396 }
397 // TODO: check shapes.
398 }
399};
400
405template <typename F>
407 FockVector<F> result(a);
408 result += b;
409 return result;
410}
415template <typename F>
417 a += b;
418 return a;
419}
424template <typename F>
426 b += a;
427 return b;
428}
429
434template <typename F>
436 FockVector<F> result(a);
437 result -= b;
438 return result;
439}
444template <typename F>
446 a -= b;
447 return a;
448}
453template <typename F>
455 b -= a;
456 // TODO: directly invoke sum to prevent extra multiplication by -1
457 b *= F(-1);
458 return b;
459}
460
465template <typename F>
466inline FockVector<F> operator*(const FockVector<F> &a, const F s) {
467 FockVector<F> result(a);
468 result *= s;
469 return result;
470}
476template <typename F>
477inline FockVector<F> &&operator*(FockVector<F> &&a, const F s) {
478 a *= s;
479 return a;
480}
481
486template <typename F>
487inline FockVector<F> operator*(const F s, const FockVector<F> &a) {
488 FockVector<F> result(a);
489 result *= s;
490 return result;
491}
497template <typename F>
498inline FockVector<F> &&operator*(const F s, FockVector<F> &&a) {
499 a *= s;
500 return a;
501}
502
507template <typename F>
508inline std::ostream &operator<<(std::ostream &stream, const FockVector<F> &a) {
509 stream << "( ";
510 stream << a.get(0) << "[" << a.get_indices(0) << "]";
511 for (size_t i(1); i < a.component_tensors.size(); ++i) {
512 stream << ", " << a.get(i) << "[" << a.get_indices(i) << "]";
513 }
514 return stream << " )";
515}
516
517template <typename F, int N, int StartDimension = 0>
519public:
520 using FockVector<F>::FockVector;
521
525 FockVectorNdCanonical(const unsigned int No, const unsigned int Nv) {
526 if (N > 6) {
527 throw new EXCEPTION("FockVectorNdCanonical implemented only up to 6");
528 }
529 const std::string pindices("abcdefgABCDEFG");
530 const std::string hindices("ijklomnIJKLOMN");
531 for (unsigned int i(StartDimension); i <= N / 2; i++) {
532
533 // vec<int> and not unsigned int, otherwise you'll be miserable for at
534 // least two days.
535 std::vector<int> syms(i, NS);
536 std::vector<int> dimso(i, No);
537 std::vector<int> dimsv(i, Nv);
538 std::vector<int> dims(dimsv);
539 dims.insert(dims.end(), dimso.begin(), dimso.end());
540
541 this->component_indices.push_back(pindices.substr(0, i)
542 + hindices.substr(0, i));
543 this->component_tensors.push_back(
544 NEW(Tensor<F>, 2 * i, dims.data(), syms.data(), *Sisi4s::world));
545 }
547 }
548
553
558 this->component_tensors = a.component_tensors;
559 this->component_indices = a.component_indices;
560 this->index_ends.resize(a.component_tensors.size());
561
563 }
564
569 this->component_tensors.resize(a.component_tensors.size());
570 this->component_indices = a.component_indices;
571 this->index_ends.resize(a.component_tensors.size());
573
575 }
576};
577
578template <typename F>
580template <typename F>
582template <typename F>
584
585template <typename F>
586class SDFockVector;
587
588template <typename F>
589class SFockVector : public FockVectorNdCanonical<F, 1, 1> {
590public:
592
594 : FockVectorNdCanonical<F, 1, 1>(0, 0) {}
595
597 this->component_indices = a.component_indices;
598 this->index_ends.resize(1);
599 this->component_tensors.resize(1);
602 }
603
605 this->component_indices = a.component_indices;
606 this->component_tensors = a.component_tensors;
607 this->index_ends.resize(1);
609 }
610
612 this->component_indices = a.component_indices;
615 return *this;
616 }
617
619 this->component_indices = a.component_indices;
620 this->index_ends.resize(1);
621 this->component_tensors.resize(1);
624 }
625};
626
627template <typename F>
628class SDTFockVector;
629
630template <typename F>
631class SDFockVector : public FockVectorNdCanonical<F, 2, 1> {
632public:
634
636 : FockVectorNdCanonical<F, 2, 1>(0, 0) {}
637
639 this->component_indices = a.component_indices;
640 this->index_ends.resize(2);
641 this->component_tensors.resize(2);
644 }
645
647 this->component_indices = a.component_indices;
648 this->component_tensors = a.component_tensors;
649 this->index_ends.resize(2);
651 }
652
654 this->component_indices = a.component_indices;
657 return *this;
658 }
659
661 this->component_indices = a.component_indices;
662 this->index_ends.resize(2);
663 this->component_tensors.resize(2);
666 }
667
669 this->component_indices = a.component_indices;
670 this->index_ends.resize(2);
671 this->component_tensors.resize(2);
674 }
675};
676
677template <typename F>
678class SDTFockVector : public FockVectorNdCanonical<F, 3, 1> {
679public:
681
683 : FockVectorNdCanonical<F, 3, 1>(0, 0) {}
684
687 this->component_tensors.resize(3);
688 this->component_indices.resize(3);
689 this->component_indices[0] = a.component_indices[0];
690 this->component_indices[1] = a.component_indices[1];
691 this->component_indices[2] = "abcijk";
692 this->index_ends.resize(3);
693 // This copies the components of a
694
695 int No(this->component_tensors[0]->lens[1]);
696 int Nv(this->component_tensors[0]->lens[0]);
697 int vvvooo[6] = {Nv, Nv, Nv, No, No, No};
698 int syms[6] = {NS, NS, NS, NS, NS, NS};
699 this->component_tensors[2] =
700 NEW(Tensor<F>, 6, vvvooo, syms, *Sisi4s::world);
701 (*this->get(2))["abcijk"] = 0.0;
702
704 }
705
707 this->component_tensors.resize(3);
708 this->component_indices.resize(3);
709 this->component_indices[0] = a.component_indices[0];
710 this->component_indices[1] = a.component_indices[1];
711 this->component_indices[2] = "abcijk";
712 this->index_ends.resize(3);
713 // This copies the components of a
714 this->component_tensors[0] = a.component_tensors[0];
715 this->component_tensors[1] = a.component_tensors[1];
716
717 int No(this->component_tensors[0]->lens[1]);
718 int Nv(this->component_tensors[0]->lens[0]);
719 int vvvooo[6] = {Nv, Nv, Nv, No, No, No};
720 int syms[6] = {NS, NS, NS, NS, NS, NS};
721 this->component_tensors[2] =
722 NEW(Tensor<F>, 6, vvvooo, syms, *Sisi4s::world);
723 (*this->get(2))["abcijk"] = 0.0;
724
726 }
727
729 this->component_tensors.resize(3);
730 this->component_indices.resize(3);
731 this->component_indices[0] = a.component_indices[0];
732 this->component_indices[1] = a.component_indices[1];
733 this->component_indices[2] = "abcijk";
734 this->index_ends.resize(3);
735 // This copies the components of a
736 this->component_tensors[0] = a.component_tensors[0];
737 this->component_tensors[1] = a.component_tensors[1];
738
739 int No(this->component_tensors[0]->lens[1]);
740 int Nv(this->component_tensors[0]->lens[0]);
741 int vvvooo[6] = {Nv, Nv, Nv, No, No, No};
742 int syms[6] = {NS, NS, NS, NS, NS, NS};
743 this->component_tensors[2] =
744 NEW(Tensor<F>, 6, vvvooo, syms, *Sisi4s::world);
745 (*this->get(2))["abcijk"] = 0.0;
746
748
749 return *this;
750 }
751
754 this->component_tensors.resize(3);
755 this->component_indices.resize(3);
756 this->component_indices[0] = a.component_indices[0];
757 this->component_indices[1] = a.component_indices[1];
758 this->component_indices[2] = "abcijk";
759 this->index_ends.resize(3);
760 // This copies the components of a
761
762 int No(this->component_tensors[0]->lens[1]);
763 int Nv(this->component_tensors[0]->lens[0]);
764 int vvvooo[6] = {Nv, Nv, Nv, No, No, No};
765 int syms[6] = {NS, NS, NS, NS, NS, NS};
766 this->component_tensors[2] =
767 NEW(Tensor<F>, 6, vvvooo, syms, *Sisi4s::world);
768 (*this->get(2))["abcijk"] = 0.0;
769
771
772 return *this;
773 }
774};
775
776} // namespace sisi4s
777
778#endif
#define EXCEPTION(message)
Definition Exception.hpp:8
std::ostream & operator<<(std::ostream &s, const FcidumpReader::FcidumpHeader &h)
Definition FcidumpWriter.cxx:25
#define NEW(TYPE,...)
Definition SharedPointer.hpp:10
#define PTR(TYPE)
Definition SharedPointer.hpp:8
Definition FockVector.hpp:518
FockVectorNdCanonical(const FockVector< F > &a)
Copy constructor copying the tensors owned by a.
Definition FockVector.hpp:568
FockVectorNdCanonical(const unsigned int No, const unsigned int Nv)
Build a canonical vector from No and Nv.
Definition FockVector.hpp:525
FockVectorNdCanonical(FockVector< F > &&a)
Move constructor taking possession of the tensors owned by a.
Definition FockVector.hpp:557
FockVectorNdCanonical()
Empty constructor.
Definition FockVector.hpp:552
Represents the direct sum of Tensors and provides the vector space operations of addition,...
Definition FockVector.hpp:26
F braket(const FockVector< F > &ket) const
Returns the matrix product of this bra-FockVector with the given dual ket-FockVector ket.
Definition FockVector.hpp:208
FockVector()
Default constructor for an empty Fock vector without elements.
Definition FockVector.hpp:36
std::vector< std::pair< size_t, F > > readLocal() const
Reads out all locally stored values together with their respective indices. The indices are between 0...
Definition FockVector.hpp:284
std::vector< std::shared_ptr< Tensor< F > > > component_tensors
Definition FockVector.hpp:30
FockVector(const std::vector< std::shared_ptr< Tensor< F > > > &tensors, const std::vector< std::string > &indices)
Move constructor taking possession of the tensors given.
Definition FockVector.hpp:62
F FieldType
Definition FockVector.hpp:28
FockVector< F > conjugateTranspose() const
Creates and returns the conjugate transpose of this FockVector. The first and the second half of the ...
Definition FockVector.hpp:176
void checkDualCompatibility(const FockVector< F > &a) const
Check if two FockVectors are transpose of each other by swapping the first and the second half of the...
Definition FockVector.hpp:376
FockVector(FockVector< F > &&a)
Move constructor taking possession of the tensors owned by a.
Definition FockVector.hpp:41
FockVector< F > & operator+=(const FockVector< F > &a)
Add-to assignment operator adding each component of a to the respective component of this FockVector.
Definition FockVector.hpp:136
void build_index_translation()
Definition FockVector.hpp:348
void checkCompatibilityTo(const FockVector< F > &a) const
Definition FockVector.hpp:392
FockVector< F > & operator-=(const FockVector< F > &a)
Subtract-from assignment operator subtracting each component of a from the respective component of th...
Definition FockVector.hpp:149
std::vector< std::string > component_indices
Definition FockVector.hpp:31
FockVector< F > & operator=(const FockVector< F > &&a)
Move assignment operator taking possession of the tensors owned by a.
Definition FockVector.hpp:115
F dot(const FockVector< F > &a) const
Returns the inner product of this ket-FockVector with the given ket-FockVector a. The elements of thi...
Definition FockVector.hpp:226
size_t get_dimension() const
Get the total number of degrees of freedom represented by this FockVector, i.e. the total number of f...
Definition FockVector.hpp:249
size_t get_index(const size_t component, const size_t componentIndex) const
Definition FockVector.hpp:255
FockVector(const FockVector< F > &a)
Copy constructor copying the tensors owned by a.
Definition FockVector.hpp:51
void fromIndex(const size_t index, size_t &component, size_t &componentIndex) const
Definition FockVector.hpp:265
std::string & get_indices(const size_t i)
Retrieves the i-th component indices as modifiable string.
Definition FockVector.hpp:109
std::vector< size_t > index_ends
The end of the FockVector index range for each component. This vector is used for translating compone...
Definition FockVector.hpp:342
const std::string & get_indices(const size_t i) const
Retrieves the i-th component indices.
Definition FockVector.hpp:102
std::shared_ptr< Tensor< F > > & get(const size_t i)
Retrieves the i-th component tensor.
Definition FockVector.hpp:97
FockVector< F > & operator=(const FockVector< F > &a)
Copy assignment operator copying the tensors owned by a.
Definition FockVector.hpp:125
void copy_components(const std::vector< std::shared_ptr< Tensor< F > > > &components)
Sets this FockVector's component tensors by copying the given component tensors. Called by copy const...
Definition FockVector.hpp:364
const std::shared_ptr< Tensor< F > > & get(const size_t i) const
Retrieves the i-th component tensor. Note that the Tensor is not const since rearrangement may be req...
Definition FockVector.hpp:90
size_t get_components_count() const
Get the number of component tensors of this FockVector.
Definition FockVector.hpp:241
void write(const std::vector< std::pair< size_t, F > > &elements)
Writes the given values together with their respective indices. The indices are between 0 and get_dim...
Definition FockVector.hpp:312
FockVector(TensorsIterator tensorsBegin, TensorsIterator tensorsEnd, IndicesIterator indicesBegin, IndicesIterator indicesEnd)
Move constructor taking possession of the tensors given by the iterators.
Definition FockVector.hpp:75
FockVector< F > & operator*=(const F s)
Multiply-by assignment operator scalar multiplying each component each component of this FockVector b...
Definition FockVector.hpp:162
Definition FockVector.hpp:631
SDFockVector< F > & operator=(const SDFockVector< F > &a)
Definition FockVector.hpp:653
SDFockVector()
Definition FockVector.hpp:635
SDFockVector(const SDTFockVector< F > &a)
Definition FockVector.hpp:668
SDFockVector(const SFockVector< F > &a)
Definition FockVector.hpp:660
SDFockVector(const SDFockVector< F > &a)
Definition FockVector.hpp:638
SDFockVector(SDFockVector< F > &&a)
Definition FockVector.hpp:646
Definition FockVector.hpp:678
SDTFockVector< F > & operator=(SDFockVector< F > &&a)
Definition FockVector.hpp:728
SDTFockVector()
Definition FockVector.hpp:682
SDTFockVector(const SDFockVector< F > &a)
Definition FockVector.hpp:685
SDTFockVector(const SDFockVector< F > &&a)
Definition FockVector.hpp:706
SDTFockVector< F > & operator=(const SDFockVector< F > &a)
Definition FockVector.hpp:752
Definition FockVector.hpp:589
SFockVector(const SFockVector< F > &a)
Definition FockVector.hpp:596
SFockVector()
Definition FockVector.hpp:593
SFockVector< F > & operator=(const SFockVector< F > &a)
Definition FockVector.hpp:611
SFockVector(SFockVector< F > &&a)
Definition FockVector.hpp:604
SFockVector(const SDFockVector< F > &a)
Definition FockVector.hpp:618
static CTF::World * world
Definition Sisi4s.hpp:17
Definition Algorithm.hpp:10
CTF::Tensor< F > Tensor
Definition Tensor.hpp:9
FockVector< F > operator+(const FockVector< F > &a, const FockVector< F > &b)
Returns the sum of two FockVectors a and b, where neither a nor b are modified.
Definition FockVector.hpp:406
std::string operator*(const std::string &s, const sisi4s::Permutation< N > &pi)
Definition CcsdPerturbativeTriples.cxx:24
FockVector< F > operator-(const FockVector< F > &a, const FockVector< F > &b)
Returns the difference between two FockVectors a and b, where neither a nor b are modified.
Definition FockVector.hpp:435