xerus
a general purpose tensor library
ttNetwork.h
Go to the documentation of this file.
1 // Xerus - A General Purpose Tensor Library
2 // Copyright (C) 2014-2017 Benjamin Huber and Sebastian Wolf.
3 //
4 // Xerus is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as published
6 // by the Free Software Foundation, either version 3 of the License,
7 // or (at your option) any later version.
8 //
9 // Xerus is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
13 //
14 // You should have received a copy of the GNU Affero General Public License
15 // along with Xerus. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // For further information on Xerus visit https://libXerus.org
18 // or contact us at contact@libXerus.org.
19 
25 #pragma once
26 
27 
28 #include "misc/containerSupport.h"
29 #include "misc/check.h"
30 
31 #include "index.h"
33 #include "tensor.h"
34 #include "tensorNetwork.h"
35 #include "indexedTensor.h"
36 #include "indexedTensorMoveable.h"
37 #include "indexedTensorList.h"
38 
39 namespace xerus {
44  template<bool isOperator>
45  class TTNetwork final : public TensorNetwork {
46  public:
48  static constexpr const size_t N = isOperator?2:1;
49 
52 
58  size_t corePosition;
59 
60 
61  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Constructors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
66  explicit TTNetwork();
67 
68 
70  TTNetwork(const TTNetwork & _cpy) = default;
71 
72 
74  TTNetwork( TTNetwork&& _mov) noexcept = default;
75 
76 
81  explicit TTNetwork(const size_t _degree);
82 
83 
88  explicit TTNetwork(Tensor::DimensionTuple _dimensions);
89 
90 
98  explicit TTNetwork(const Tensor& _tensor, const double _eps=EPSILON, const size_t _maxRank=std::numeric_limits<size_t>::max());
99 
100 
108  explicit TTNetwork(const Tensor& _tensor, const double _eps, const RankTuple& _maxRanks);
109 
110 
117 // explicit TTNetwork(const TensorNetwork &_network, double _eps=EPSILON);
118 
119 
128  template<class distribution=std::normal_distribution<value_t>, class generator=std::mt19937_64>
129  static TTNetwork XERUS_warn_unused random(std::vector<size_t> _dimensions, const std::vector<size_t> &_ranks, distribution& _dist=xerus::misc::defaultNormalDistribution, generator& _rnd=xerus::misc::randomEngine) {
130  const size_t numComponents = _dimensions.size()/N;
131  XERUS_REQUIRE(_dimensions.size()%N==0, "Illegal number of dimensions for TTOperator.");
132  XERUS_REQUIRE(_ranks.size()+1 == numComponents,"Non-matching amount of ranks given to TTNetwork::random.");
133  XERUS_REQUIRE(!misc::contains(_dimensions, size_t(0)), "Trying to construct a TTTensor with dimension 0 is not possible.");
134  XERUS_REQUIRE(!misc::contains(_ranks, size_t(0)), "Trying to construct random TTTensor with rank 0 is illegal.");
135 
136 
137 
138  TTNetwork result(_dimensions.size());
139  const std::vector<size_t> targetRank = reduce_to_maximal_ranks(_ranks, _dimensions);
140 
141  for(size_t i = 0; i < numComponents; ++i) {
142  const size_t leftRank = i==0 ? 1 : targetRank[i-1];
143  const size_t rightRank = (i==numComponents-1) ? 1 : targetRank[i];
144 
145  if(isOperator) {
146  const auto rndComp = Tensor::random({leftRank, _dimensions[i], _dimensions[numComponents+i], rightRank}, _dist, _rnd);
147  result.set_component(i, rndComp);
148  } else {
149  const auto rndComp = Tensor::random({leftRank, _dimensions[i], rightRank}, _dist, _rnd);
150  result.set_component(i, rndComp);
151  }
152  }
153  result.move_core(0);
154  return result;
155  }
156 
157 
166  template<class distribution=std::normal_distribution<value_t>, class generator=std::mt19937_64>
167  static TTNetwork XERUS_warn_unused random(const std::vector<size_t>& _dimensions, const size_t _rank, distribution& _dist=xerus::misc::defaultNormalDistribution, generator& _rnd=xerus::misc::randomEngine) {
168  return TTNetwork::random(_dimensions, std::vector<size_t>(_dimensions.size()/N-1, _rank), _dist, _rnd);
169  }
170 
171 
178  template<class distribution=std::normal_distribution<value_t>, class generator=std::mt19937_64>
179  static TTNetwork XERUS_warn_unused random(const std::vector<size_t>& _dimensions, const std::vector<size_t> &_ranks,
180  const std::function<void(Tensor&)> &_modifySingularValues,
181  distribution& _dist=xerus::misc::defaultNormalDistribution, generator& _rnd=xerus::misc::randomEngine)
182  {
183  const size_t numComponents = _dimensions.size()/N;
184 
185  TTNetwork result = random(_dimensions, _ranks, _dist, _rnd);
186 
187  const Index i,j,k,l,m;
188 
189  for (size_t pos = 0; pos+1 < numComponents; ++pos) {
190  Tensor A;
191  A(i,j^N,k^N,l) = result.component(pos)(i,j^N,m) * result.component(pos+1)(m,k^N,l);
192  Tensor U,S,Vt;
193  (U(i&1,j),S(j,k),Vt(k,l&1)) = SVD(A(i/2,l/2));
194  _modifySingularValues(S);
195  Vt(j,l&1) = S(j,k) * Vt(k,l&1);
196  result.set_component(pos, U);
197  result.set_component(pos+1, Vt);
198  result.assume_core_position(pos+1);
199  }
200 
201  result.require_correct_format();
202  XERUS_INTERNAL_CHECK(!result.exceeds_maximal_ranks(), "Internal Error");
203  result.canonicalize_left();
204  return result;
205  }
206 
207 
212  static TTNetwork XERUS_warn_unused ones(const std::vector<size_t>& _dimensions);
213 
214 
220  template<bool B = isOperator, typename std::enable_if<B, int>::type = 0>
221  static TTNetwork XERUS_warn_unused identity(const std::vector<size_t>& _dimensions);
222 
223 
229  static TTNetwork XERUS_warn_unused kronecker(const std::vector<size_t>& _dimensions);
230 
231 
237  static TTNetwork XERUS_warn_unused dirac(std::vector<size_t> _dimensions, const std::vector<size_t>& _position);
238 
239 
245  static TTNetwork XERUS_warn_unused dirac(std::vector<size_t> _dimensions, const size_t _position);
246 
247  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Standard Operators - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
249  TTNetwork& operator=(const TTNetwork& _other) = default;
250 
251 
253  TTNetwork& operator=( TTNetwork&& _other) = default;
254 
255 
256  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Internal helper functions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
257  protected:
259  static void construct_train_from_full(TensorNetwork& _out, const Tensor& _A, const double _eps);
260 
261 
267  bool exceeds_maximal_ranks() const;
268 
269 
271  size_t num_ranks() const;
272 
273  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Miscellaneous - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
274  public:
282  static std::vector<size_t> reduce_to_maximal_ranks(std::vector<size_t> _ranks, const std::vector<size_t>& _dimensions);
283 
287  static size_t degrees_of_freedom(const std::vector<size_t> &_dimensions, const std::vector<size_t> &_ranks);
288 
292  size_t degrees_of_freedom();
293 
294  virtual void fix_mode(const size_t _mode, const size_t _slatePosition) override;
295 
296  virtual void resize_mode(const size_t _mode, const size_t _newDim, const size_t _cutPos=~0ul) override;
297 
303 
311  Tensor& component(const size_t _idx);
312 
313 
323  const Tensor& get_component(const size_t _idx) const;
324 
325 
335  void set_component(const size_t _idx, Tensor _T);
336 
337 
344  std::pair<TensorNetwork, TensorNetwork> chop(const size_t _position) const;
345 
346 
352  void round(const std::vector<size_t>& _maxRanks, const double _eps = EPSILON);
353 
354 
359  void round(const size_t _maxRank);
360 
361 
366  void round(const int _maxRank);
367 
368 
373  void round(const value_t _eps);
374 
375 
380  void soft_threshold(const double _tau, const bool _preventZero = false);
381 
382 
387  void soft_threshold(const std::vector<double>& _taus, const bool _preventZero = false);
388 
389 
394  std::vector<size_t> ranks() const;
395 
396 
402  size_t rank(const size_t _i) const;
403 
404 
413  void move_core(const size_t _position, const bool _keepRank=false);
414 
415 
421  void assume_core_position(const size_t _pos);
422 
423 
428  void canonicalize_left();
429 
430 
435  void canonicalize_right();
436 
437 
442  template<bool B = isOperator, typename std::enable_if<B, int>::type = 0>
443  void transpose() {
444  const std::vector<size_t> shuffle({0,2,1,3});
445  for (size_t n = 0; n < degree()/N; ++n) {
446  xerus::reshuffle(component(n), component(n), shuffle);
447  }
448  }
449 
450 
451  virtual TensorNetwork* get_copy() const override;
452 
453 
454  virtual void contract_unconnected_subnetworks() override;
455 
456 
457  virtual value_t frob_norm() const override;
458 
459 
464  virtual void require_correct_format() const override;
465 
466 
467  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Basic arithmetics - - - - - - - - - - - - - - - - - - - - - - - - - - */
475  TTNetwork& operator+=(const TTNetwork& _other);
476 
477 
485  TTNetwork& operator-=(const TTNetwork& _other);
486 
492  virtual void operator*=(const value_t _factor) override;
493 
499  virtual void operator/=(const value_t _divisor) override;
500 
501  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Operator specializations - - - - - - - - - - - - - - - - - - - - - - - - - - */
503 
505 
507  return specialized_contraction_f(_out, std::move(_me), std::move(_other));
508  }
509 
511  return specialized_sum_f(_out, std::move(_me), std::move(_other));
512  }
513 
515 
516  };
517 
518  typedef TTNetwork<false> TTTensor;
519  typedef TTNetwork<true> TTOperator;
520 
521 
530  template<bool isOperator>
532 
533 
542  template<bool isOperator>
544 
545 
553  template<bool isOperator>
555 
556 
564  template<bool isOperator>
566 
567 
574  template<bool isOperator>
576 
577 
582  template<bool isOperator>
584 
591  template<bool isOperator>
593 
594 
600  template<bool isOperator>
601  TTNetwork<isOperator> dyadic_product(const std::vector<TTNetwork<isOperator>> &_tensors);
602 
603 
604  namespace misc {
605 
610  template<bool isOperator>
611  void stream_writer(std::ostream& _stream, const TTNetwork<isOperator> &_obj, misc::FileFormat _format);
612 
616  template<bool isOperator>
617  void stream_reader(std::istream& _stream, TTNetwork<isOperator> &_obj, const misc::FileFormat _format);
618  }
619 }
virtual void resize_mode(const size_t _mode, const size_t _newDim, const size_t _cutPos=~0ul) override
Resizes a specific mode of the TensorNetwork.
Definition: ttNetwork.cpp:438
std::pair< TensorNetwork, TensorNetwork > chop(const size_t _position) const
Splits the TTNetwork into two parts by removing the node.
Definition: ttNetwork.cpp:515
Header file for CHECK and REQUIRE macros.
static TTNetwork XERUS_warn_unused identity(const std::vector< size_t > &_dimensions)
: Construct a TTOperator with the given dimensions representing the identity.
Helper class to allow an intuitive syntax for SVD factorisations.
void assume_core_position(const size_t _pos)
stores _pos as the current core position without verifying of ensuring that this is the case ...
Definition: ttNetwork.cpp:735
static constexpr const size_t N
The number of external links in each node, i.e. one for TTTensors and two for TTOperators.
Definition: ttNetwork.h:48
Internal representation of an read and write and moveable indexed Tensor or TensorNetwork.
static bool specialized_contraction_f(std::unique_ptr< internal::IndexedTensorMoveable< TensorNetwork >> &_out, internal::IndexedTensorReadOnly< TensorNetwork > &&_me, internal::IndexedTensorReadOnly< TensorNetwork > &&_other)
void reshuffle(Tensor &_out, const Tensor &_base, const std::vector< size_t > &_shuffle)
: Performs a simple reshuffle. Much less powerfull then a full evaluate, but more efficient...
void transpose()
Transpose the TTOperator.
Definition: ttNetwork.h:443
void soft_threshold(const double _tau, const bool _preventZero=false)
Applies the soft threshholding operation to all ranks.
Definition: ttNetwork.cpp:711
Header file for the Index class.
Header file for the IndexedTensorMoveable class.
Header file defining lists of indexed tensors.
Header file for the standard contaienr support functions.
static Tensor XERUS_warn_unused random(DimensionTuple _dimensions, distribution &_dist=xerus::misc::defaultNormalDistribution, generator &_rnd=xerus::misc::randomEngine)
Constructs a dense Tensor with the given dimensions and uses the given random generator and distribut...
Definition: tensor.h:213
Tensor & component(const size_t _idx)
Complete access to a specific component of the TT decomposition.
Definition: ttNetwork.cpp:457
Very general class used to represent arbitary tensor networks.
Definition: tensorNetwork.h:42
Internal representation of an readable indexed Tensor or TensorNetwork.
Header file for the classes defining factorisations of Tensors.
TTNetwork< true > TTOperator
static bool specialized_sum_f(std::unique_ptr< internal::IndexedTensorMoveable< TensorNetwork >> &_out, internal::IndexedTensorReadOnly< TensorNetwork > &&_me, internal::IndexedTensorReadOnly< TensorNetwork > &&_other)
Definition: ttNetwork.cpp:982
Specialized TensorNetwork class used to represent TTTensor and TToperators.
The main namespace of xerus.
Definition: basic.h:37
Class that handles simple (non-decomposed) tensors in a dense or sparse representation.
Definition: tensor.h:70
static TTNetwork XERUS_warn_unused random(const std::vector< size_t > &_dimensions, const std::vector< size_t > &_ranks, const std::function< void(Tensor &)> &_modifySingularValues, distribution &_dist=xerus::misc::defaultNormalDistribution, generator &_rnd=xerus::misc::randomEngine)
Random constructs a TTNetwork with the given dimensions and ranks.
Definition: ttNetwork.h:179
thread_local std::normal_distribution< double > defaultNormalDistribution
Definition: random.cpp:30
virtual void specialized_evaluation(internal::IndexedTensorWritable< TensorNetwork > &&_me, internal::IndexedTensorReadOnly< TensorNetwork > &&_other) override
(Internal) Evaluates _other into _me. Requires that *this is the tensorObjectReadOnly of _me...
Definition: ttNetwork.cpp:1064
#define XERUS_INTERNAL_CHECK(condition, message)
Checks whether condition is true. logs a critical error otherwise via XERUS_LOG(fatal, message). and prints information on how to report a bug.
Definition: check.h:67
void canonicalize_right()
Move the core to the left.
Definition: ttNetwork.cpp:638
bool canonicalized
Flag indicating whether the TTNetwork is canonicalized.
Definition: ttNetwork.h:51
Tensor operator*(const value_t _factor, Tensor _tensor)
Calculates the entrywise multiplication of the Tensor _tensor with the constant _factor.
Definition: tensor.cpp:1233
std::vector< size_t > DimensionTuple
: Represention of the dimensions of a Tensor.
Definition: tensor.h:92
size_t degree() const
Gets the degree of the TensorNetwork.
static void construct_train_from_full(TensorNetwork &_out, const Tensor &_A, const double _eps)
Constructs a TTNetwork in _out by decomposing the given Tensor _A.
#define XERUS_warn_unused
Definition: standard.h:78
Header file for the Tensor class.
void move_core(const size_t _position, const bool _keepRank=false)
Move the core to a new position.
Definition: ttNetwork.cpp:582
TTNetwork()
Constructs an order zero TTNetwork.
Definition: ttNetwork.cpp:46
TTNetwork< false > TTTensor
std::vector< size_t > ranks() const
Gets the ranks of the TTNetwork.
Definition: ttNetwork.cpp:717
FileFormat
possible file formats for tensor storage
Definition: fileIO.h:43
static TTNetwork XERUS_warn_unused ones(const std::vector< size_t > &_dimensions)
: Returns a the (rank one) TT-Tensor with all entries equal to one.
Definition: ttNetwork.cpp:170
void set_component(const size_t _idx, Tensor _T)
Sets a specific component of the TT decomposition.
Definition: ttNetwork.cpp:471
void use_dense_representations()
Converts all components to use dense representations.
Definition: ttNetwork.cpp:450
Tensor operator-(Tensor _lhs, const Tensor &_rhs)
Calculates the entrywise difference between _lhs and _rhs.
Definition: tensor.cpp:1227
static TTNetwork XERUS_warn_unused random(std::vector< size_t > _dimensions, const std::vector< size_t > &_ranks, distribution &_dist=xerus::misc::defaultNormalDistribution, generator &_rnd=xerus::misc::randomEngine)
Transforms a given TensorNetwork to a TTNetwork.
Definition: ttNetwork.h:129
TTNetwork & operator=(const TTNetwork &_other)=default
TTNetworks are default assignable.
virtual void fix_mode(const size_t _mode, const size_t _slatePosition) override
Fixes a specific mode to a specific value, effectively reducing the order by one. ...
Definition: ttNetwork.cpp:432
#define XERUS_REQUIRE(condition, message)
Checks whether condition is true. logs an error otherwise via XERUS_LOG(error, message).
Definition: check.h:65
constexpr const value_t EPSILON
The default epsilon value in xerus.
Definition: basic.h:50
bool exceeds_maximal_ranks() const
Tests whether any rank exceeds the theoretic maximal value it should have.
Definition: ttNetwork.cpp:349
Tensor operator+(Tensor _lhs, const Tensor &_rhs)
Calculates the entrywise sum of _lhs and _rhs.
Definition: tensor.cpp:1221
static TTNetwork XERUS_warn_unused random(const std::vector< size_t > &_dimensions, const size_t _rank, distribution &_dist=xerus::misc::defaultNormalDistribution, generator &_rnd=xerus::misc::randomEngine)
Random constructs a TTNetwork with the given dimensions and ranks limited by the given rank...
Definition: ttNetwork.h:167
virtual bool specialized_sum(std::unique_ptr< internal::IndexedTensorMoveable< TensorNetwork >> &_out, internal::IndexedTensorReadOnly< TensorNetwork > &&_me, internal::IndexedTensorReadOnly< TensorNetwork > &&_other) const override
(Internal) Calculates the sum between _me and _other and stores the result in _out. Requires that *this is the tensorObjectReadOnly of _me.
Definition: ttNetwork.h:510
static std::vector< size_t > reduce_to_maximal_ranks(std::vector< size_t > _ranks, const std::vector< size_t > &_dimensions)
Reduces the given ranks to the maximal possible.
Definition: ttNetwork.cpp:370
static TTNetwork XERUS_warn_unused dirac(std::vector< size_t > _dimensions, const std::vector< size_t > &_position)
: Returns a TTNetwork with a single entry equals oen and all other zero.
Definition: ttNetwork.cpp:257
virtual TensorNetwork * get_copy() const override
Returns a new copy of the network.
Definition: ttNetwork.cpp:743
Abstract internal representation of an read and writeable indexed Tensor or TensorNetwork.
double value_t
The type of values to be used by xerus.
Definition: basic.h:43
virtual value_t frob_norm() const override
Calculates the frobenious norm of the TensorNetwork.
Definition: ttNetwork.cpp:782
void stream_writer(std::ostream &_stream, const TTNetwork< isOperator > &_obj, misc::FileFormat _format)
Pipes all information necessary to restore the current TensorNetwork into _stream.
Definition: ttNetwork.cpp:1455
virtual void require_correct_format() const override
Tests whether the network resembles that of a TTTensor and checks consistency with the underlying ten...
Definition: ttNetwork.cpp:290
Class used to represent indices that can be used to write tensor calculations in index notation...
Definition: index.h:43
static TTNetwork XERUS_warn_unused kronecker(const std::vector< size_t > &_dimensions)
: Returns a TTNetwork representation of the kronecker delta.
Definition: ttNetwork.cpp:224
std::vector< size_t > RankTuple
: Represention of the ranks of a TensorNetwork.
Definition: tensorNetwork.h:45
TTNetwork< isOperator > dyadic_product(const TTNetwork< isOperator > &_lhs, const TTNetwork< isOperator > &_rhs)
Computes the dyadic product of _lhs and _rhs.
Definition: ttNetwork.cpp:1319
size_t degrees_of_freedom()
calculates the number of degrees of freedom of the manifold of fixed tt-rank that the given TTTensor ...
Definition: ttNetwork.cpp:426
thread_local std::mt19937_64 randomEngine
virtual bool specialized_contraction(std::unique_ptr< internal::IndexedTensorMoveable< TensorNetwork >> &_out, internal::IndexedTensorReadOnly< TensorNetwork > &&_me, internal::IndexedTensorReadOnly< TensorNetwork > &&_other) const override
(Internal) Calculates the contraction between _me and _other and stores the result in _out...
Definition: ttNetwork.h:506
TTNetwork & operator-=(const TTNetwork &_other)
Subtracts the _other TTNetwork entrywise from this one.
Definition: ttNetwork.cpp:851
Header file for the TensorNetwork class.
virtual void contract_unconnected_subnetworks() override
Contracts all nodes that are not connected to any external links.
Definition: ttNetwork.cpp:748
Tensor entrywise_product(const Tensor &_A, const Tensor &_B)
calculates the entrywise product of two Tensors
Definition: tensor.cpp:1708
TTNetwork & operator+=(const TTNetwork &_other)
Adds a given TTNetwork to this one.
Definition: ttNetwork.cpp:797
size_t rank(const size_t _i) const
Gets the rank of a specific egde of the TTNetwork.
Definition: ttNetwork.cpp:728
virtual void operator/=(const value_t _divisor) override
Calculates the entrywise divison of this TensorNetwork by a constant _divisor.
Definition: ttNetwork.cpp:872
size_t num_ranks() const
Return the number of ranks, i.e. 0 for degree zero and degree()/N-1 otherwise.
Definition: ttNetwork.cpp:363
void canonicalize_left()
Move the core to the left.
Definition: ttNetwork.cpp:632
void round(const std::vector< size_t > &_maxRanks, const double _eps=EPSILON)
Reduce all ranks up to a given accuracy and maximal number.
Definition: ttNetwork.cpp:644
const Tensor & get_component(const size_t _idx) const
Read access to a specific component of the TT decomposition.
Definition: ttNetwork.cpp:464
size_t corePosition
The position of the core.
Definition: ttNetwork.h:58
internal::IndexedTensorMoveable< Tensor > operator/(internal::IndexedTensorReadOnly< Tensor > &&_b, internal::IndexedTensorReadOnly< Tensor > &&_A)
void stream_reader(std::istream &_stream, TTNetwork< isOperator > &_obj, const misc::FileFormat _format)
Restores the TTNetwork from a stream of data.
Definition: ttNetwork.cpp:1475
Header file for the IndexedTensor class.
virtual void operator*=(const value_t _factor) override
Calculates the entrywise multiplication of this TensorNetwork with a constant _factor.
Definition: ttNetwork.cpp:860