xerus
a general purpose tensor library
iht.cpp
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 #include <xerus.h>
26 #include "../../../include/xerus/misc/internal.h"
27 
28 namespace xerus {
29  double IHT(TTTensor& _x, const SinglePointMeasurementSet& _measurments, PerformanceData& _perfData) {
30  const size_t numMeasurments = _measurments.size();
31  const size_t degree = _x.degree();
32  const size_t USER_MEASUREMENTS_PER_ITR = numMeasurments;
33  const value_t ALPHA_CHG = 1.1;
34 
35 
36  TTTensor largeX(_x);
37  // SinglePointMeasurementSet currentValues(_measurments);
38  std::vector<value_t> currentValues(numMeasurments);
39  std::vector<size_t> measurementOrder(numMeasurments);
40  std::iota(measurementOrder.begin(), measurementOrder.end(), 0);
41 
42  _perfData.start();
43 
44  Index i1, i2, i3, i4, i5;
45 
46 // std::mt19937_64 rnd(rd());
47 // std::uniform_real_distribution<value_t> dist(0, 1);
48 
49  std::vector<size_t> twoR(_x.ranks());
50  for (auto &r : twoR) {
51  r *= 2;
52  }
53 
54  double alpha = 1;
55 
56  value_t residual = 1;
57 
58  for(size_t iteration = 0; iteration < 1000000; ++iteration) {
59 // _x.measure(currentValues);
60 
61  for(size_t i = 0; i < numMeasurments; ++i) {
62  currentValues[i] = _x[_measurments.positions[i]];
63  }
64 
65 // std::shuffle(measurementOrder.begin(), measurementOrder.end(), rnd);
66 // std::sort(measurementOrder.begin(), measurementOrder.end(), [&](size_t a, size_t b){
67 // return std::abs(_measurments.measuredValues[a] - currentValues[a]) > std::abs(_measurments.measuredValues[b] - currentValues[b]);
68 // });
69 
70  value_t bestResidual = residual*2;
71  value_t newAlpha = alpha;
72 
73  for (value_t beta = 1/ALPHA_CHG; beta < ALPHA_CHG*1.5; beta *= ALPHA_CHG) {
74  // Build the largeX
75  for(size_t d = 0; d < degree; ++d) {
76  Tensor& currComp = _x.component(d);
77  Tensor newComp({d == 0 ? 1 : (currComp.dimensions[0]+USER_MEASUREMENTS_PER_ITR), currComp.dimensions[1], d == degree-1 ? 1 : (currComp.dimensions[2]+USER_MEASUREMENTS_PER_ITR)});
78 
79  // Copy dense part
80  for(size_t r1 = 0; r1 < currComp.dimensions[0]; ++r1) {
81  for(size_t n = 0; n < currComp.dimensions[1]; ++n) {
82  for(size_t r2 = 0; r2 < currComp.dimensions[2]; ++r2) {
83  newComp[{r1, n, r2}] = currComp[{r1, n, r2}];
84  }
85  }
86  }
87 
88  // Copy sparse part
89  if (d==0) {
90  for(size_t i = 0; i < USER_MEASUREMENTS_PER_ITR; ++i) {
91  newComp[{0, _measurments.positions[measurementOrder[i]][d], i+currComp.dimensions[2]}] = beta*alpha*(_measurments.measuredValues[measurementOrder[i]] - currentValues[measurementOrder[i]]);
92  }
93  } else if (d!=degree-1) {
94  for(size_t i = 0; i < USER_MEASUREMENTS_PER_ITR; ++i) {
95  newComp[{i + currComp.dimensions[0], _measurments.positions[measurementOrder[i]][d], i+currComp.dimensions[2]}] = 1.0;
96  }
97  } else {
98  // d == degree-1
99  for(size_t i = 0; i < USER_MEASUREMENTS_PER_ITR; ++i) {
100  newComp[{i + currComp.dimensions[0], _measurments.positions[measurementOrder[i]][d], 0}] = 1.0;
101  }
102  }
103 
104 
105  largeX.set_component(d, newComp);
106  }
107  // one ALS sweep to 2r
108  TTTensor newX = _x;//TTTensor::random(_x.dimensions, twoR, dist);
109  for (size_t o=0; o<1; ++o) {
110  newX.move_core(0, true);
111  // build stack from right to left
112  std::vector<Tensor> stack;
113  stack.emplace_back(Tensor::ones({1,1}));
114  for (size_t i=degree-1; i>0; --i) {
115  Tensor next;
116  next(i1,i2) = newX.get_component(i)(i1,i5,i3) * largeX.get_component(i)(i2,i5,i4) * stack.back()(i3,i4);
117  stack.emplace_back(next);
118  }
119  Tensor left = Tensor::ones({1,1});
120  // sweep left to right
121  for (size_t i=0; i<degree; ++i) {
122  newX.component(i)(i1,i2,i3) = left(i1,i4) * largeX.get_component(i)(i4,i2,i5) * stack.back()(i3,i5);
123  if (i+1<degree) {
124  newX.move_core(i+1, true);
125  left(i1,i2) = left(i3,i4) * newX.get_component(i)(i3,i5,i1) * largeX.get_component(i)(i4,i5,i2);
126  stack.pop_back();
127  }
128  }
129  }
130  residual = 0;
131 
132  for(size_t i = 0; i < numMeasurments; ++i) {
133  residual += misc::sqr(_measurments.measuredValues[i] - newX[_measurments.positions[i]]);
134  }
135  residual = std::sqrt(residual);
136 
137 // LOG(best, beta*alpha << " " << residual);
138 
139  // newX.round(_x.ranks(), 0.0);
140  if (residual <= bestResidual) {
141  _x = newX;
142  bestResidual = residual;
143  newAlpha = alpha * beta;
144  }
145  }
146  residual = bestResidual;
147  alpha = newAlpha;
148  LOG(newAlpha, alpha);
149 
150  _perfData.add(iteration, bestResidual, _x, 0);
151  }
152 
153  return residual;
154  }
155 } // namespace xerus
Tensor & component(const size_t _idx)
Complete access to a specific component of the TT decomposition.
Definition: ttNetwork.cpp:457
Class used to represent a single point measurments.
Definition: measurments.h:43
#define LOG
Definition: internal.h:38
DimensionTuple dimensions
Vector containing the individual dimensions of the tensor.
Definition: tensor.h:99
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
Storage class for the performance data collected during an algorithm (typically iteration count...
static Tensor XERUS_warn_unused ones(DimensionTuple _dimensions)
: Returns a Tensor with all entries equal to one.
Definition: tensor.cpp:122
size_t degree() const
Gets the degree of the TensorNetwork.
void move_core(const size_t _position, const bool _keepRank=false)
Move the core to a new position.
Definition: ttNetwork.cpp:582
std::vector< size_t > ranks() const
Gets the ranks of the TTNetwork.
Definition: ttNetwork.cpp:717
void set_component(const size_t _idx, Tensor _T)
Sets a specific component of the TT decomposition.
Definition: ttNetwork.cpp:471
Default include file for the xerus library.
double IHT(TTTensor &_x, const SinglePointMeasurementSet &_measurments, PerformanceData &_perfData=NoPerfData)
Definition: iht.cpp:29
constexpr T sqr(const T &_a) noexcept
: Calculates _a*_a.
Definition: math.h:43
double value_t
The type of values to be used by xerus.
Definition: basic.h:43
Class used to represent indices that can be used to write tensor calculations in index notation...
Definition: index.h:43
std::vector< std::vector< size_t > > positions
Definition: measurments.h:45
std::vector< value_t > measuredValues
Definition: measurments.h:46
void add(const size_t _itrCount, const value_t _residual, const TensorNetwork::RankTuple _ranks=TensorNetwork::RankTuple(), const size_t _flags=0)
const Tensor & get_component(const size_t _idx) const
Read access to a specific component of the TT decomposition.
Definition: ttNetwork.cpp:464