Cytnx v1.0.0
Loading...
Searching...
No Matches
LinOp.hpp
Go to the documentation of this file.
1#ifndef CYTNX_LINOP_H_
2#define CYTNX_LINOP_H_
3
4#include "Type.hpp"
5#include "cytnx_error.hpp"
6#include <vector>
7#include <fstream>
8#include <functional>
9#include <map>
10#include <utility>
11#include <algorithm>
13#include "Tensor.hpp"
14#include "UniTensor.hpp"
15
16namespace cytnx {
17
18 class LinOp {
19 private:
20 // type:
21 std::string _type;
22
23 // nx
24 cytnx_uint64 _nx;
25
26 // device
27 int _device;
28 int _dtype;
29
30 // pre-storage data:
31 std::map<cytnx_uint64, std::pair<std::vector<cytnx_uint64>, Tensor>>
32 _elems; // map[i] -> pair[<js>,<Storage>]
33 std::map<cytnx_uint64, std::pair<std::vector<cytnx_uint64>, Tensor>>::iterator _elems_it;
34
35 Tensor _mv_elemfunc(const Tensor &);
36
37 public:
39 // we need driver of void f(nx,vin,vout)
41
68 LinOp(const std::string &type, const cytnx_uint64 &nx, const int &dtype = Type.Double,
69 const int &device = Device.cpu) {
70 if (type == "mv") {
71 } else if (type == "mv_elem") {
72 } else
73 cytnx_error_msg(type != "mv",
74 "[ERROR][LinOp] currently only type=\"mv\" (matvec) can be used.%s", "\n");
75
76 this->_type = type;
77 this->_nx = nx;
78 cytnx_error_msg(device < -1 || device >= Device.Ngpus, "[ERROR] invalid device.%s", "\n");
79 this->_device = device;
80 cytnx_error_msg(dtype < 1 || dtype >= N_Type, "[ERROR] invalid dtype.%s", "\n");
81 this->_dtype = dtype;
82 };
83 /*
84 void set_func(std::function<Tensor(const Tensor&)> custom_f, const int &dtype, const int
85 &device){ if(this->_type=="mv"){ this->_mvfunc = custom_f; cytnx_error_msg(device<-1 || device
86 >=Device.Ngpus,"[ERROR] invalid device.%s","\n"); this->_device = device;
87 cytnx_error_msg(dtype<1 || dtype >= N_Type,"[ERROR] invalid dtype.%s","\n");
88 this->_dtype = dtype;
89 }else{
90 cytnx_error_msg(true,"[ERROR] Cannot specify func with type=mv_elem%s. use set_elem
91 instead.","\n");
92 }
93 };
94 */
95 template <class T>
96 void set_elem(const cytnx_uint64 &i, const cytnx_uint64 &j, const T &elem,
97 const bool check_exists = true) {
98 this->_elems_it = this->_elems.find(i);
99 if (this->_elems_it == this->_elems.end()) {
100 // not exists:
101 Tensor x({1}, this->_dtype);
102 x(0) = elem;
103 this->_elems[i] = std::pair<std::vector<cytnx_uint64>, Tensor>({j}, x);
104
105 } else {
106 std::vector<cytnx_uint64> &vi = this->_elems_it->second.first; // pair:
107 Tensor &ie = this->_elems_it->second.second;
108 if (check_exists) {
109 cytnx_error_msg(std::find(vi.begin(), vi.end(), j) != vi.end(),
110 "[ERROR] the element is set%s", "\n");
111 }
112 vi.push_back(j);
113 ie.append(elem);
114 }
115 };
117 //[Note that this can only call by mv_elem]
118 // if the element is not exists, it will create one.
119 this->_elems_it = this->_elems.find(i);
120 if (this->_elems_it == this->_elems.end()) {
121 // not exists:
122 Tensor x({1}, this->_dtype);
123 x(0) = 0;
124 this->_elems[i] = std::pair<std::vector<cytnx_uint64>, Tensor>({j}, x);
125 return this->_elems[i].second(0);
126 } else {
127 std::vector<cytnx_uint64> &vi = this->_elems_it->second.first; // pair:
128 Tensor &ie = this->_elems_it->second.second;
129 auto tmp_it = std::find(vi.begin(), vi.end(), j);
130
131 // if(check_exists){
132 // cytnx_error_msg(std::find(vi.begin(), vi.end(), j)!=vi.end(),"[ERROR] the element is
133 // set%s","\n");
134 // }
135 if (tmp_it == vi.end()) {
136 vi.push_back(j);
137 ie.append(0);
138 return ie(vi.size() - 1);
139 } else {
140 return ie(std::distance(vi.begin(), tmp_it));
141 }
142 }
143 }
144
145 void set_device(const int &device) {
146 cytnx_error_msg(device < -1 || device >= Device.Ngpus, "[ERROR] invalid device.%s", "\n");
147 this->_device = device;
148 };
149 void set_dtype(const int &dtype) {
150 cytnx_error_msg(dtype < 1 || dtype >= N_Type, "[ERROR] invalid dtype.%s", "\n");
151 this->_dtype = dtype;
152 };
153 int device() const { return this->_device; };
154 int dtype() const { return this->_dtype; };
155 cytnx_uint64 nx() const { return this->_nx; };
156
157 void _print();
158
160 // this expose to interitance:
161 // need user to check the output to be Tensor
163 virtual Tensor matvec(const Tensor &Tin);
164
166 // this expose to interface:
167 virtual UniTensor matvec(const UniTensor &Tin);
168 // virtual std::vector<UniTensor> matvec(const std::vector<UniTensor> &Tin);
170 };
171
172} // namespace cytnx
173
174#endif // CYTNX_LINOP_H_
constexpr Type_class Type
data type
Definition Type.hpp:553
Definition LinOp.hpp:18
virtual Tensor matvec(const Tensor &Tin)
int device() const
Definition LinOp.hpp:153
LinOp(const std::string &type, const cytnx_uint64 &nx, const int &dtype=Type.Double, const int &device=Device.cpu)
Linear Operator class for iterative solvers.
Definition LinOp.hpp:68
int dtype() const
Definition LinOp.hpp:154
cytnx_uint64 nx() const
Definition LinOp.hpp:155
void set_elem(const cytnx_uint64 &i, const cytnx_uint64 &j, const T &elem, const bool check_exists=true)
Definition LinOp.hpp:96
void set_device(const int &device)
Definition LinOp.hpp:145
void set_dtype(const int &dtype)
Definition LinOp.hpp:149
Tensor::Tproxy operator()(const cytnx_uint64 &i, const cytnx_uint64 &j)
Definition LinOp.hpp:116
an tensor (multi-dimensional array)
Definition Tensor.hpp:33
int device() const
the device-id of the Tensor
Definition Tensor.hpp:581
An Enhanced tensor specifically designed for physical Tensor network simulation.
Definition UniTensor.hpp:2773
#define cytnx_error_msg(is_true, format,...)
Definition cytnx_error.hpp:118
Definition Accessor.hpp:12
Device_class Device
data on which devices.