xerus
a general purpose tensor library
adf.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 "../index.h"
28 #include "../ttNetwork.h"
29 #include "../performanceData.h"
30 #include "../measurments.h"
31 
32 namespace xerus {
33 
39  class ADFVariant {
40  protected:
41 
42  template<class MeasurmentSet>
44  /*
45  * General notation for the ADF:
46  * The vector of the measured values is denoted as b
47  * The measurment operator is denoted as A. It holds by definition A(x) = b (for noiseless measurments).
48  * The Operator constructed from the x by removing the component at corePosition is denoted as E.
49  */
50 
51  protected:
53  const Index r1, r2, i1;
54 
57 
59  const size_t degree;
60 
62  const std::vector<size_t> maxRanks;
63 
65  const MeasurmentSet& measurments;
66 
68  const size_t numMeasurments;
69 
72 
74  const size_t maxIterations;
75 
77  const double targetResidualNorm;
78 
81 
83  size_t iteration;
84 
86  double residualNorm;
87 
90 
92  std::vector<value_t> residual;
93 
96 
98  std::unique_ptr<Tensor*[]> forwardStackMem;
99 
106  Tensor* const * const forwardStack;
107 
109  std::unique_ptr<Tensor[]> forwardStackSaveSlots;
110 
112  std::vector<std::vector<size_t>> forwardUpdates;
113 
114 
116  std::unique_ptr<Tensor*[]> backwardStackMem;
117 
124  Tensor* const * const backwardStack;
125 
127  std::unique_ptr<Tensor[]> backwardStackSaveSlots;
128 
130  std::vector<std::vector<size_t>> backwardUpdates;
131 
133  std::unique_ptr<double[]> measurmentNorms;
134 
137 
139  static double calculate_norm_of_measured_values(const MeasurmentSet& _measurments);
140 
142  void construct_stacks(std::unique_ptr< xerus::Tensor[] >& _stackSaveSlot, std::vector< std::vector< size_t > >& _updates, const std::unique_ptr<Tensor*[]>& _stackMem, const bool _forward);
143 
145  void resize_stack_tensors();
146 
148  std::vector<Tensor> get_fixed_components(const Tensor& _component);
149 
153  void update_forward_stack(const size_t _corePosition, const Tensor& _currentComponent);
154 
158  void update_backward_stack(const size_t _corePosition, const Tensor& _currentComponent);
159 
161  void calculate_residual( const size_t _corePosition );
162 
164  template<class PositionType>
165  void perform_dyadic_product(const size_t _localLeftRank, const size_t _localRightRank, const value_t* const _leftPtr, const value_t* const _rightPtr, value_t* const _deltaPtr, const value_t _residual, const PositionType& _position, value_t* const _scratchSpace );
166 
167 
169  void calculate_projected_gradient(const size_t _corePosition);
170 
176  std::vector<value_t> calculate_slicewise_norm_A_projGrad( const size_t _corePosition);
177 
179  void update_x(const std::vector<value_t>& _normAProjGrad, const size_t _corePosition);
180 
183 
184  public:
186  double solve();
187 
189  const std::vector<size_t>& _maxRanks,
190  const MeasurmentSet& _measurments,
191  const size_t _maxIteration,
192  const double _targetResidualNorm,
193  const double _minimalResidualNormDecrease,
194  PerformanceData& _perfData ) :
195  x(_x),
196  degree(_x.degree()),
197  maxRanks(TTTensor::reduce_to_maximal_ranks(_maxRanks, _x.dimensions)),
198 
199  measurments(_measurments),
200  numMeasurments(_measurments.size()),
201  normMeasuredValues(calculate_norm_of_measured_values(_measurments)),
202 
203  maxIterations(_maxIteration),
204  targetResidualNorm(_targetResidualNorm),
205  minimalResidualNormDecrease(_minimalResidualNormDecrease),
206 
207  iteration(0),
208  residualNorm(std::numeric_limits<double>::max()),
209  lastResidualNorm(std::numeric_limits<double>::max()),
210 
211  residual(numMeasurments),
212 
213  forwardStackMem(new Tensor*[numMeasurments*(degree+2)]),
214  forwardStack(forwardStackMem.get()+numMeasurments),
215  forwardUpdates(degree),
216 
217  backwardStackMem(new Tensor*[numMeasurments*(degree+2)]),
218  backwardStack(backwardStackMem.get()+numMeasurments),
219  backwardUpdates(degree),
220 
221  measurmentNorms(new double[numMeasurments]),
222 
223  perfData(_perfData)
224  {
226  XERUS_REQUIRE(numMeasurments > 0, "Need at very least one measurment.");
227  XERUS_REQUIRE(measurments.degree() == degree, "Measurment degree must coincide with x degree.");
228  }
229 
230  };
231 
232  public:
233  size_t maxIterations;
235  double minimalResidualNormDecrease; // The minimal relative decrease of the residual per step ( i.e. (lastResidual-residual)/lastResidual ). If the avg. of the last three steps is smaller than this value, the algorithm stops.
236 
238  ADFVariant(const size_t _maxIteration, const double _targetResidual, const double _minimalResidualDecrease)
239  : maxIterations(_maxIteration), targetResidualNorm(_targetResidual), minimalResidualNormDecrease(_minimalResidualDecrease) { }
240 
248  template<class MeasurmentSet>
249  double operator()(TTTensor& _x, const MeasurmentSet& _measurments, PerformanceData& _perfData) const {
251  return solver.solve();
252  }
253 
262  template<class MeasurmentSet>
263  double operator()(TTTensor& _x, const MeasurmentSet& _measurments, const std::vector<size_t>& _maxRanks, PerformanceData& _perfData) const {
264  InternalSolver<MeasurmentSet> solver(_x, _maxRanks, _measurments, maxIterations, targetResidualNorm, minimalResidualNormDecrease, _perfData);
265  return solver.solve();
266  }
267  };
268 
270  extern const ADFVariant ADF;
271 }
272 
double residualNorm
Current residual norm. Updated at the beginning of each iteration.
Definition: adf.h:86
std::unique_ptr< Tensor *[]> backwardStackMem
Ownership holder for a (degree+2)*numMeasurments array of Tensor pointers. (Not used directly) ...
Definition: adf.h:116
std::vector< Tensor > get_fixed_components(const Tensor &_component)
Returns a vector of tensors containing the slices of _component where the second dimension is fixed...
Definition: adf.cpp:207
void update_backward_stack(const size_t _corePosition, const Tensor &_currentComponent)
For each measurment sets the backwardStack at the given _corePosition to the contraction between the ...
std::vector< value_t > residual
The current residual, saved as vector (instead of a order one tensor).
Definition: adf.h:92
void update_forward_stack(const size_t _corePosition, const Tensor &_currentComponent)
For each measurment sets the forwardStack at the given _corePosition to the contraction between the f...
void construct_stacks(std::unique_ptr< xerus::Tensor[] > &_stackSaveSlot, std::vector< std::vector< size_t > > &_updates, const std::unique_ptr< Tensor *[]> &_stackMem, const bool _forward)
Constructes either the forward or backward stack. That is, it determines the groups of partially equa...
Definition: adf.cpp:103
PerformanceData & perfData
: Reference to the performanceData object (external ownership)
Definition: adf.h:136
void solve_with_current_ranks()
Basically the complete algorithm, trying to reconstruct x using its current ranks.
Definition: adf.cpp:490
std::vector< std::vector< size_t > > forwardUpdates
Vector containing for each corePosition a vector of the smallest ids of each group of unique forwardS...
Definition: adf.h:112
void calculate_projected_gradient(const size_t _corePosition)
: Calculates the component at _corePosition of the projected gradient from the residual, i.e. E(A^T(b-Ax)).
Definition: adf.cpp:360
double targetResidualNorm
Target residual. The algorithm will stop upon reaching a residual smaller than this value...
Definition: adf.h:234
void perform_dyadic_product(const size_t _localLeftRank, const size_t _localRightRank, const value_t *const _leftPtr, const value_t *const _rightPtr, value_t *const _deltaPtr, const value_t _residual, const PositionType &_position, value_t *const _scratchSpace)
Calculates one internal step of calculate_projected_gradient. In particular the dyadic product of the...
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
STL namespace.
double solve()
Tries to solve the reconstruction problem with the current settings.
Definition: adf.cpp:567
const double minimalResidualNormDecrease
Minimal relative decrease of the residual norm ( (oldRes-newRes)/oldRes ) until either the ranks are ...
Definition: adf.h:80
Tensor *const *const backwardStack
Array [numMeasurments][degree]. For positions larger than the current corePosition and for each measu...
Definition: adf.h:124
Storage class for the performance data collected during an algorithm (typically iteration count...
const size_t degree
Degree of the solution.
Definition: adf.h:59
Wrapper class for all ADF variants.
Definition: adf.h:39
const ADFVariant ADF
Default variant of the ADF algorithm.
size_t iteration
The current iteration.
Definition: adf.h:83
Tensor *const *const forwardStack
Array [numMeasurments][degree]. For positions smaller than the current corePosition and for each meas...
Definition: adf.h:106
std::unique_ptr< Tensor[]> forwardStackSaveSlots
Ownership holder for the unqiue Tensors referenced in forwardStack.
Definition: adf.h:109
std::vector< size_t > ranks() const
Gets the ranks of the TTNetwork.
Definition: ttNetwork.cpp:717
std::vector< value_t > calculate_slicewise_norm_A_projGrad(const size_t _corePosition)
: Calculates ||P_n (A(E(A^T(b-Ax)))))|| = ||P_n (A(E(A^T(residual)))))|| = ||P_n (A(E(gradient)))|| f...
Definition: adf.cpp:414
std::unique_ptr< Tensor *[]> forwardStackMem
Ownership holder for a (degree+2)*numMeasurments array of Tensor pointers. (Not used directly) ...
Definition: adf.h:98
void calculate_residual(const size_t _corePosition)
(Re-)Calculates the current residual, i.e. Ax-b.
Definition: adf.cpp:291
std::unique_ptr< double[]> measurmentNorms
: Norm of each rank one measurment operator
Definition: adf.h:133
const std::vector< size_t > maxRanks
Maximally allowed ranks.
Definition: adf.h:62
double operator()(TTTensor &_x, const MeasurmentSet &_measurments, const std::vector< size_t > &_maxRanks, PerformanceData &_perfData) const
Tries to reconstruct the (low rank) tensor _x from the given measurments.
Definition: adf.h:263
double minimalResidualNormDecrease
Definition: adf.h:235
InternalSolver(TTTensor &_x, const std::vector< size_t > &_maxRanks, const MeasurmentSet &_measurments, const size_t _maxIteration, const double _targetResidualNorm, const double _minimalResidualNormDecrease, PerformanceData &_perfData)
Definition: adf.h:188
#define XERUS_REQUIRE(condition, message)
Checks whether condition is true. logs an error otherwise via XERUS_LOG(error, message).
Definition: check.h:65
const double targetResidualNorm
The target residual norm at which the algorithm shall stop.
Definition: adf.h:77
double operator()(TTTensor &_x, const MeasurmentSet &_measurments, PerformanceData &_perfData) const
Tries to reconstruct the (low rank) tensor _x from the given measurments.
Definition: adf.h:249
const value_t normMeasuredValues
The two norm of the measured values.
Definition: adf.h:71
double value_t
The type of values to be used by xerus.
Definition: basic.h:43
std::vector< std::vector< size_t > > backwardUpdates
Vector containing for each corePosition a vector of the smallest ids of each group of unique backward...
Definition: adf.h:130
const size_t numMeasurments
Number of measurments (i.e. measurments.size())
Definition: adf.h:68
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
void resize_stack_tensors()
Resizes the unqiue stack tensors to correspond to the current ranks of x.
Definition: adf.cpp:194
ADFVariant(const size_t _maxIteration, const double _targetResidual, const double _minimalResidualDecrease)
fully defining constructor. alternatively ALSVariants can be created by copying a predefined variant ...
Definition: adf.h:238
Class used to represent indices that can be used to write tensor calculations in index notation...
Definition: index.h:43
static double calculate_norm_of_measured_values(const MeasurmentSet &_measurments)
calculates the two-norm of the measured values.
Definition: adf.cpp:37
const MeasurmentSet & measurments
Reference to the measurment set (external ownership)
Definition: adf.h:65
size_t maxIterations
Maximum number of sweeps to perform. Set to 0 for infinite.
Definition: adf.h:233
std::unique_ptr< Tensor[]> backwardStackSaveSlots
Ownership holder for the unqiue Tensors referenced in backwardStack.
Definition: adf.h:127
double lastResidualNorm
The residual norm of the last iteration.
Definition: adf.h:89
const size_t maxIterations
Maximal allowed number of iterations (one iteration = one sweep)
Definition: adf.h:74
Tensor projectedGradientComponent
The current projected Gradient component. That is E(A^T(Ax-b))
Definition: adf.h:95
const Index r1
Indices for all internal functions.
Definition: adf.h:53
TTTensor & x
Reference to the current solution (external ownership)
Definition: adf.h:56
void update_x(const std::vector< value_t > &_normAProjGrad, const size_t _corePosition)
Updates the current solution x. For SinglePointMeasurments the is done for each slice speratly...