xerus
a general purpose tensor library
tensorNetwork.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 #include <set>
28 #include <memory>
29 #include <functional>
30 #include "misc/fileIO.h"
31 
32 #include "indexedTensor.h"
33 
34 namespace xerus {
35  // Necessary forward declaritons
36  class Tensor;
37 
42  class TensorNetwork {
43  public:
45  using RankTuple = std::vector<size_t>;
46 
50  class Link final {
51  public:
53  size_t other;
54 
56  size_t indexPosition;
57 
59  size_t dimension;
60 
62  bool external;
63 
64  Link() noexcept = default;
65  Link(const Link& ) noexcept = default;
66  Link( Link&&) noexcept = default;
67 
68  Link(const size_t _other, const size_t _indexPos, const size_t _dim, const bool _external) noexcept;
69 
70  Link& operator=(const Link& ) noexcept = default;
71  Link& operator=( Link&&) noexcept = default;
72 
78  bool links(const size_t _other) const noexcept;
79  };
80 
81 
85  class TensorNode final {
86  public:
88  std::unique_ptr<Tensor> tensorObject;
89 
91  std::vector<Link> neighbors;
92 
94  bool erased;
95 
96  explicit TensorNode();
97 
98  TensorNode(const TensorNode& _other);
99  TensorNode( TensorNode&& _other) noexcept = default;
100 
101  explicit TensorNode( std::unique_ptr<Tensor>&& _tensorObject);
102 
103  explicit TensorNode(std::unique_ptr<Tensor>&& _tensorObject, std::vector<Link> _neighbors);
104 
105  ~TensorNode();
106 
107  TensorNode& operator=(const TensorNode& _other);
108  TensorNode& operator=( TensorNode&& _other) noexcept;
109 
110  TensorNode strippped_copy() const;
111 
112  // All getters are written without the use of tensorObject so that they also work for empty nodes
113 
114  size_t size() const noexcept;
115 
116  size_t degree() const noexcept;
117 
118  void erase() noexcept;
119  };
120 
121  protected:
122 
126  enum class ZeroNode : bool { None, Add };
127 
128 
129  public:
130  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Member variables - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
131 
133  std::vector<size_t> dimensions;
134 
136  std::vector<TensorNode> nodes;
137 
139  std::vector<Link> externalLinks;
140 
141  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Constructors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
142 
147  explicit TensorNetwork();
148 
149 
151  TensorNetwork(const TensorNetwork& _cpy) = default;
152 
153 
155  TensorNetwork(TensorNetwork&& _mv) noexcept = default;
156 
157 
161  TensorNetwork(Tensor _other);
162 
163 
168  TensorNetwork(std::unique_ptr<Tensor>&& _tensor);
169 
170 
176  TensorNetwork(size_t _degree);
177 
184  explicit TensorNetwork(const ZeroNode _nodeStatus);
185 
186 
188  virtual ~TensorNetwork() = default;
189 
190 
194  virtual TensorNetwork* get_copy() const;
195 
196  protected:
197  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Internal Helper functions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
199  std::vector<Link> init_from_dimension_array();
200 
201 
209  TensorNetwork stripped_subnet(const std::function<bool(size_t)>& _idF = [](size_t){ return true;}) const;
210 
211 
215  virtual void contract_unconnected_subnetworks();
216 
217 
222  void perform_traces(const size_t _nodeId);
223 
224  public:
225 
232  std::pair<size_t, size_t> find_common_edge(const size_t _nodeA, const size_t _nodeB) const;
233 
234 
235 
240  void sanitize();
241 
242 
243  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Standard operators - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
244 
246  TensorNetwork& operator=(const TensorNetwork &_cpy) = default;
247 
249  TensorNetwork& operator=(TensorNetwork &&_mv) = default;
250 
251 
252  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Conversions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
253 
258  explicit operator Tensor() const;
259 
260  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Access - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
268  value_t operator[](const size_t _position) const;
269 
270 
278  value_t operator[](const std::vector<size_t>& _positions) const;
279 
280 
281  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Basic arithmetics - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
282 
288  virtual void operator*=(const value_t _factor);
289 
290 
296  virtual void operator/=(const value_t _divisor);
297 
298 
299  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Indexing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
305  template<typename... args>
307  return internal::IndexedTensor<TensorNetwork>(this, std::vector<Index>({_args...}), false);
308  }
309 
310 
316  template<typename... args>
318  return internal::IndexedTensorReadOnly<TensorNetwork>(this, std::vector<Index>({_args...}));
319  }
320 
321 
327  internal::IndexedTensor<TensorNetwork> operator()(const std::vector<Index> & _indices);
328 
329 
335  internal::IndexedTensor<TensorNetwork> operator()( std::vector<Index>&& _indices);
336 
337 
343  internal::IndexedTensorReadOnly<TensorNetwork> operator()(const std::vector<Index> & _indices) const;
344 
345 
351  internal::IndexedTensorReadOnly<TensorNetwork> operator()( std::vector<Index>&& _indices) const;
352 
353 
354  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Operator specializations - - - - - - - - - - - - - - - - - - - - - - - - - - */
355 
358 
359 
362 
363 
366 
367  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Miscellaneous - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
368 
375  size_t degree() const;
376 
381  size_t datasize() const;
382 
383 
385  void reshuffle_nodes(const std::function<size_t(size_t)>& _f);
386 
387 
395  void require_valid_network(const bool _check_erased = true) const;
396 
397 
404  virtual void require_correct_format() const;
405 
406 
411  void swap_external_links(const size_t _i, const size_t _j);
412 
413 
418 
419 
425 
426 
427 
428  public:
439  virtual void round_edge(const size_t _nodeA, const size_t _nodeB, const size_t _maxRank, const double _eps, const double _softThreshold);
440 
441 
449  virtual void transfer_core(const size_t _from, const size_t _to, const bool _allowRankReduction = true);
450 
451 
456  void reduce_representation();
457 
458 
464  virtual void fix_mode(const size_t _mode, const size_t _slatePosition);
465 
469  virtual void remove_slate(const size_t _mode, const size_t _slatePosition);
470 
479  virtual void resize_mode(const size_t _mode, const size_t _newDim, const size_t _cutPos=~0ul);
480 
487  void contract(const size_t _nodeId1, const size_t _nodeId2);
488 
489 
496  double contraction_cost(const size_t _nodeId1, const size_t _nodeId2) const;
497 
498 
505  size_t contract(const std::set<size_t>& _ids);
506 
507 
512  virtual value_t frob_norm() const;
513 
514 
520  void draw(const std::string& _filename) const;
521  };
522 
524 
526 
528 
534  static XERUS_force_inline value_t frob_norm(const TensorNetwork& _network) { return _network.frob_norm(); }
535 
536 
545  bool approx_equal(const TensorNetwork& _a, const TensorNetwork& _b, const value_t _eps = EPSILON);
546 
547 
551  bool approx_equal(const TensorNetwork& _a, const Tensor& _b, const value_t _eps = EPSILON);
552 
553 
557  bool approx_equal(const Tensor& _a, const TensorNetwork& _b, const value_t _eps = EPSILON);
558 
559 
560  std::ostream &operator<<(std::ostream &_out, const TensorNetwork::Link &_rhs);
561 
562  namespace misc {
567  void stream_writer(std::ostream &_stream, const TensorNetwork &_obj, const FileFormat _format);
568 
572  void stream_reader(std::istream &_stream, TensorNetwork &_obj, const FileFormat _format);
573  }
574 }
static void add_network_to_network(internal::IndexedTensorWritable< TensorNetwork > &&_base, internal::IndexedTensorReadOnly< TensorNetwork > &&_toInsert)
Inserts all nodes from _toInsert into _base, creating links where demanded by the indices...
void contract(const size_t _nodeId1, const size_t _nodeId2)
Contracts the nodes with indices _nodeId1 and _nodeId2.
TensorNetwork stripped_subnet(const std::function< bool(size_t)> &_idF=[](size_t){ return true;}) const
Creates a dataless copy of a subnet.
void draw(const std::string &_filename) const
Draws a graph representation of the TensorNetwork.
static void link_traces_and_fix(internal::IndexedTensorWritable< TensorNetwork > &&_base)
Finds traces defined by the indices and internally links the corresponding indices. Also applys all fixed indices.
Internal representation of an read and write and moveable indexed Tensor or TensorNetwork.
void sanitize()
Removes all erased nodes from the TensorNetwork.
virtual void remove_slate(const size_t _mode, const size_t _slatePosition)
removes the given _slatePosition from the _mode. this reduces the given dimension by one ...
ZeroNode
Internal indicator to prevent the creation of an degree zero node in TensorNetwork constructor...
virtual TensorNetwork * get_copy() const
Returns a new copy of the network.
std::pair< size_t, size_t > find_common_edge(const size_t _nodeA, const size_t _nodeB) const
Finds the position of a single common edge between two nodes.
virtual void contract_unconnected_subnetworks()
Contracts all nodes that are not connected to any external links.
Very general class used to represent arbitary tensor networks.
Definition: tensorNetwork.h:42
Internal representation of an readable indexed Tensor or TensorNetwork.
size_t datasize() const
Calculates the storage requirement of the current representation.
The TensorNode class is used by the class TensorNetwork to store the componentent tensors defining th...
Definition: tensorNetwork.h:85
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
Header file for templates to store and restore objects from / to files / streams. ...
Tensor operator*(const value_t _factor, Tensor _tensor)
Calculates the entrywise multiplication of the Tensor _tensor with the constant _factor.
Definition: tensor.cpp:1233
internal::IndexedTensorReadOnly< TensorNetwork > operator()(args... _args) const
Indexes the TensorNetwork for read only use.
void perform_traces(const size_t _nodeId)
Performs all traces in the given node.
std::ostream & operator<<(std::ostream &_out, const xerus::Index &_idx)
Allows to pretty print indices, giving the valueId and span.
Definition: index.cpp:175
void reduce_representation()
Contracts all nodes that are joined by a full-rank edge.
size_t degree() const
Gets the degree of the TensorNetwork.
value_t operator[](const size_t _position) const
Read the value at a specific position.
Internal representation of an readable and writeable indexed Tensor or TensorNetwork.
Definition: indexedTensor.h:37
double contraction_cost(const size_t _nodeId1, const size_t _nodeId2) const
Approximates the cost of contraction two given nodes.
virtual bool specialized_contraction(std::unique_ptr< internal::IndexedTensorMoveable< TensorNetwork >> &_out, internal::IndexedTensorReadOnly< TensorNetwork > &&_me, internal::IndexedTensorReadOnly< TensorNetwork > &&_other) const
(Internal) Calculates the contraction between _me and _other and stores the result in _out...
FileFormat
possible file formats for tensor storage
Definition: fileIO.h:43
virtual void require_correct_format() const
Sanity check for the TensorNetwork and if applicable for the specific format.
void reshuffle_nodes(const std::function< size_t(size_t)> &_f)
reshuffled the nodes according to the given function
virtual void resize_mode(const size_t _mode, const size_t _newDim, const size_t _cutPos=~0ul)
Resizes a specific mode of the TensorNetwork.
virtual bool specialized_sum(std::unique_ptr< internal::IndexedTensorMoveable< TensorNetwork >> &_out, internal::IndexedTensorReadOnly< TensorNetwork > &&_me, internal::IndexedTensorReadOnly< TensorNetwork > &&_other) const
(Internal) Calculates the sum between _me and _other and stores the result in _out. Requires that *this is the tensorObjectReadOnly of _me.
TensorNetwork()
Constructs an order zero TensorNetwork.
constexpr const value_t EPSILON
The default epsilon value in xerus.
Definition: basic.h:50
std::vector< Link > externalLinks
The open links of the network in order.
void stream_writer(std::ostream &_stream, const TensorNetwork &_obj, const FileFormat _format)
Pipes all information necessary to restore the current TensorNetwork into _stream.
void require_valid_network(const bool _check_erased=true) const
Sanity checks the network.
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 ~TensorNetwork()=default
Destructor.
std::vector< size_t > RankTuple
: Represention of the ranks of a TensorNetwork.
Definition: tensorNetwork.h:45
bool approx_equal(const xerus::Tensor &_a, const xerus::Tensor &_b, const xerus::value_t _eps=EPSILON)
Checks whether two tensors are approximately equal.
Definition: tensor.cpp:1738
std::unique_ptr< Tensor > tensorObject
Save slot for the tensorObject associated with this node.
Definition: tensorNetwork.h:88
virtual void operator/=(const value_t _divisor)
Performs the entrywise divison by a constant _divisor.
virtual value_t frob_norm() const
Calculates the frobenious norm of the TensorNetwork.
std::vector< Link > init_from_dimension_array()
: Sets the externalLinks and returns an Link vector for a node, assuming that this node is the only n...
virtual void transfer_core(const size_t _from, const size_t _to, const bool _allowRankReduction=true)
Transfers the core from one given node to another.
virtual void fix_mode(const size_t _mode, const size_t _slatePosition)
Fixes a specific mode to a specific value, effectively reducing the order by one. ...
std::vector< Link > neighbors
Vector of links defining the connection of this node to the network.
Definition: tensorNetwork.h:91
virtual void round_edge(const size_t _nodeA, const size_t _nodeB, const size_t _maxRank, const double _eps, const double _softThreshold)
Thresholds the rank between two given nodes.
void swap_external_links(const size_t _i, const size_t _j)
Swaps the external indices _i and _j, effectively changing those indices for the represented Tensor (...
#define XERUS_force_inline
Collection of attributes to force gcc to inline a specific function.
Definition: standard.h:75
internal::IndexedTensor< TensorNetwork > operator()(args... _args)
Indexes the TensorNetwork for read/write use.
virtual void operator*=(const value_t _factor)
Performs the entrywise multiplication with a constant _factor.
std::vector< TensorNode > nodes
The nodes constituting the network. The order determines the ids of the nodes.
internal::IndexedTensorMoveable< Tensor > operator/(internal::IndexedTensorReadOnly< Tensor > &&_b, internal::IndexedTensorReadOnly< Tensor > &&_A)
virtual void specialized_evaluation(internal::IndexedTensorWritable< TensorNetwork > &&_me, internal::IndexedTensorReadOnly< TensorNetwork > &&_other)
(Internal) Evaluates _other into _me. Requires that *this is the tensorObjectReadOnly of _me...
Header file for the IndexedTensor class.
std::vector< size_t > dimensions
Dimensions of the external indices, i.e. the dimensions of the tensor represented by the network...
void stream_reader(std::istream &_stream, TensorNetwork &_obj, const FileFormat _format)
Restores the TensorNetwork from a stream of data.