Commit 2c881eff authored by Michael Goette's avatar Michael Goette

changed HTFormat

parent 5cfa25a4
Pipeline #1035 failed with stages
in 9 minutes and 54 seconds
......@@ -133,8 +133,9 @@ namespace xerus {
template<class distribution=std::normal_distribution<value_t>, class generator=std::mt19937_64>
static HTNetwork 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) {
const size_t numIntComp = static_cast<size_t>(0.5 + std::pow(2,std::ceil(std::log2(static_cast<double>(_dimensions.size()/N ))))) - 1;
const size_t numOfLeaves = _dimensions.size()/N;
const size_t numIntComp = numOfLeaves - 1;
const size_t numComponents = numIntComp + numOfLeaves;
XERUS_REQUIRE(_dimensions.size()%N==0, "Illegal number of dimensions/Leaves for HTOperator.");
......@@ -184,7 +185,7 @@ namespace xerus {
*/
template<class distribution=std::normal_distribution<value_t>, class generator=std::mt19937_64>
static HTNetwork XERUS_warn_unused random(const std::vector<size_t>& _dimensions, const size_t _rank, distribution& _dist=xerus::misc::defaultNormalDistribution, generator& _rnd=xerus::misc::randomEngine) {
return HTNetwork::random(_dimensions, std::vector<size_t>((static_cast<size_t>(std::pow(2,std::ceil(std::log2(static_cast<double>(_dimensions.size()/N ))))) - 2 + _dimensions.size()/N), _rank), _dist, _rnd);
return HTNetwork::random(_dimensions, std::vector<size_t>(2 * _dimensions.size()/N - 2, _rank), _dist, _rnd);
}
......
......@@ -88,8 +88,8 @@ static misc::UnitTest ht_diff("HT", "difference", [](){
static misc::UnitTest ht_real_diff("HT", "real_difference", [](){
HTTensor htA = HTTensor::random({10,10,10,10,10}, {4,4,4,4,4,4,4,4,4,4,4});
HTTensor htB = HTTensor::random({10,10,10,10,10}, {4,4,4,4,4,4,4,4,4,4,4});
HTTensor htA = HTTensor::random({10,10,10,10,10}, {4,4,4,4,4,4,4,4});
HTTensor htB = HTTensor::random({10,10,10,10,10}, {4,4,4,4,4,4,4,4});
HTTensor htC(5);
Index i;
......@@ -103,10 +103,11 @@ static misc::UnitTest ht_real_diff("HT", "real_difference", [](){
MTEST(frob_norm(htC(i&0)) < 1e-9, "3 " << frob_norm(htC(i&0)));
htC(i&0) = (htA(i&0) + htB(i&0));
TEST(htC.ranks() == std::vector<size_t>({ 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 1, 1, 1 }));
TEST(htC.ranks() == std::vector<size_t>({ 8, 8, 8, 8, 8, 8, 8, 8 }));
htC(i&0) = (htB(i&0) + htA(i&0));
TEST(htC.ranks() == std::vector<size_t>({ 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 1, 1, 1 }));
TEST(htC.ranks() == std::vector<size_t>({ 8, 8, 8, 8, 8, 8, 8, 8 }));
htC(i&0) = (htA(i&0) + htB(i&0)) - (htB(i&0) + htA(i&0));
MTEST(frob_norm(htC(i&0)) < 1e-9, "4 " << frob_norm(htC(i&0)));
......@@ -114,7 +115,7 @@ static misc::UnitTest ht_real_diff("HT", "real_difference", [](){
htC(i&0) = (73*htA(i&0) + htB(i&0)) - (htB(i&0) + 73*htA(i&0));
MTEST(frob_norm(htC(i&0)) < 1e-7, "5 " << frob_norm(htC(i&0)));
htA = HTTensor::random({10,10,10,10,10}, {2,5,7,2,4,4,3,6,5,2,4});
htA = HTTensor::random({10,10,10,10,10}, {2,5,7,2,4,4,3,6});
htC(i&0) = htA(i&0) - htA(i&0);
MTEST(frob_norm(htC(i&0)) < 1e-9, "6 " << frob_norm(htC(i&0)));
......@@ -190,8 +191,8 @@ static misc::UnitTest ht_spec_sumdiff("HT", "special_sum_diff", [](){
MTEST(frob_norm(Tensor(htC)(i&0) - C(i&0)) < 5*1e-12, frob_norm(Tensor(htC)(i&0) - C(i&0)));
MTEST(frob_norm(Tensor(htC)(i&0) - Tensor(htB)(i&0)) < 3.1*1e-12, frob_norm(Tensor(htC)(i&0) - Tensor(htB)(i&0)));
Tensor X({10});
Tensor Y = Tensor::random({10});
Tensor X({10,10});
Tensor Y = Tensor::random({10,10});
Tensor Z;
HTTensor htX(X);
HTTensor htY(Y);
......@@ -320,8 +321,8 @@ static misc::UnitTest ht_trans("HT", "transpose", [](){
});
static misc::UnitTest ht_axb("HT", "ax_b", [](){
HTTensor X = HTTensor::random({10,10,10}, {2,2,2,2,2});
HTTensor B = HTTensor::random({10,10,10}, {2,2,2,2,2});
HTTensor X = HTTensor::random({10,10,10}, {2,2,2,2});
HTTensor B = HTTensor::random({10,10,10}, {2,2,2,2});
Tensor I({10,10,10,10,10,10}, [](const std::vector<size_t> &_idx) {
if (_idx[0]==_idx[3] && _idx[1] == _idx[4] && _idx[2] == _idx[5]) {
......
This diff is collapsed.
......@@ -58,9 +58,9 @@ namespace xerus {
}
const size_t numOfLeaves = degree()/N;
const size_t numOfFullLeaves = numOfLeaves == 1 ? 2 : static_cast<size_t>(0.5+std::pow(2,std::ceil(std::log2(static_cast<double>(numOfLeaves)))));
const size_t numIntComp = numOfFullLeaves - 1;
const size_t numComponents = numIntComp + numOfLeaves;
const size_t numNodes = numOfFullLeaves + numIntComp + 1;
const size_t numIntComp = numOfLeaves - 1;
//const size_t numComponents = numIntComp + numOfLeaves;
const size_t numNodes = numOfLeaves + numIntComp + 1;
const size_t stackSize = nodes.size()/numNodes;
INTERNAL_CHECK(nodes.size()%numNodes == 0, "IE");
......@@ -78,16 +78,25 @@ namespace xerus {
reshuffle_nodes([numNodes](const size_t _i){return _i%(numNodes);});
INTERNAL_CHECK(nodes.size() == numNodes, "Internal Error.");
std::vector<size_t> leaf_order;
for (size_t i = numOfFullLeaves - 1; i < numIntComp + numOfLeaves; ++i)
leaf_order.emplace_back(i-numIntComp);
for (size_t i = numOfLeaves - 1; i < numOfFullLeaves - 1 ; ++i)
leaf_order.emplace_back(i-numIntComp);
// Reset to new external links
for(size_t i = 0; i < numOfLeaves; ++i) {
externalLinks[i].other = i+numIntComp;
externalLinks[i].indexPosition = 1;
size_t ii = 0;
for(size_t i: leaf_order) {
externalLinks[ii].other = i+numIntComp;
externalLinks[ii].indexPosition = 1;
++ii;
}
if(isOperator) {
for(size_t i = 0; i < numOfLeaves; ++i) {
externalLinks[numOfLeaves+i].other = i+numIntComp;
externalLinks[numOfLeaves+i].indexPosition = 2;
ii = 0;
for(size_t i: leaf_order) {
externalLinks[numOfLeaves+ii].other = i+numIntComp;
externalLinks[numOfLeaves+ii].indexPosition = 2;
++ii;
}
}
......@@ -160,13 +169,8 @@ namespace xerus {
std::vector<size_t> shuffle_leaves(N + stackSize);
for (size_t i = numIntComp; i < numNodes - 1; ++i) {
size_t parentCount = 0, parentDim = 1, fullDim = 1;
//Dummy components
if(i >= numComponents){
nodes[i].tensorObject->reinterpret_dimensions({1});
nodes[i].neighbors.resize(1);
nodes[i].neighbors.front().other = (i-1)/2;
nodes[i].neighbors.front().indexPosition = (i-1)%2 + 1;
} else {
std::vector<size_t>::iterator itr = std::find(leaf_order.begin(), leaf_order.end(), i - numIntComp);
size_t leaf_order_pos = static_cast<size_t>(std::distance(leaf_order.begin(), itr));
for(size_t k = 0; k < N + stackSize; ++k) {
INTERNAL_CHECK(!nodes[i].erased, "IE");
const TensorNetwork::Link& link = nodes[i].neighbors[k];
......@@ -185,23 +189,23 @@ namespace xerus {
parentDim *= link.dimension;
}
else
INTERNAL_CHECK(false, "Internal Error, something wrong with the links of the TTN");
INTERNAL_CHECK(false, "Internal Error, something wrong with the links of the HTN");
}
}
INTERNAL_CHECK(fullDim == nodes[i].tensorObject->size, "Uhh");
INTERNAL_CHECK(parentCount == stackSize, "IE");
xerus::reshuffle(*nodes[i].tensorObject, *nodes[i].tensorObject, shuffle_leaves);
if(isOperator) {
nodes[i].tensorObject->reinterpret_dimensions({parentDim, dimensions[i - numIntComp], dimensions[i - numIntComp+numOfLeaves]});
nodes[i].tensorObject->reinterpret_dimensions({parentDim, dimensions[leaf_order_pos], dimensions[leaf_order_pos+numOfLeaves]});
} else {
nodes[i].tensorObject->reinterpret_dimensions({parentDim, dimensions[i - numIntComp]});
nodes[i].tensorObject->reinterpret_dimensions({parentDim, dimensions[leaf_order_pos]});
}
nodes[i].neighbors.clear();
nodes[i].neighbors.emplace_back( (i-1) / 2, i%2 == 1 ? 1:2, parentDim, false);
nodes[i].neighbors.emplace_back(-1, i - numIntComp , dimensions[i - numIntComp], true);
if(isOperator) { nodes[i].neighbors.emplace_back(-1, numOfLeaves+i - numIntComp, dimensions[numOfLeaves+i - numIntComp], true); }
}
nodes[i].neighbors.emplace_back(-1, leaf_order_pos , dimensions[leaf_order_pos], true);
if(isOperator) { nodes[i].neighbors.emplace_back(-1, numOfLeaves+leaf_order_pos, dimensions[numOfLeaves+leaf_order_pos], true); }
}
// Create actual HTNetwork
HTNetwork<isOperator> result;
......@@ -254,9 +258,9 @@ namespace xerus {
}
const size_t numOfLeaves = _me.tensorObject->degree()/N;
const size_t numOfFullLeaves = numOfLeaves == 1 ? 2 : static_cast<size_t>(0.5+std::pow(2,std::ceil(std::log2(static_cast<double>(numOfLeaves)))));
const size_t numIntComp = numOfFullLeaves - 1;
const size_t numComponents = numIntComp + numOfLeaves;
const size_t numNodes = numOfFullLeaves + numIntComp + 1;
const size_t numIntComp = numOfLeaves - 1;
//const size_t numComponents = numIntComp + numOfLeaves;
const size_t numNodes = numOfLeaves + numIntComp + 1;
const size_t stackSize = _me.tensorObject->nodes.size()/numNodes;
INTERNAL_CHECK(_me.tensorObject->nodes.size()%numNodes == 0, "IE");
......@@ -272,22 +276,31 @@ namespace xerus {
}
// Reshuffle the nodes to be in the correct order after contraction the nodes will have one of the ids: node, node+numNodes, node+2*numNodes,... (as those were part of the contraction) so modulus gives the correct wanted id.
_me.tensorObject->reshuffle_nodes([numNodes](const size_t _i){return _i%(numNodes);});
std::vector<size_t> leaf_order;
for (size_t i = numOfFullLeaves - 1; i < numIntComp + numOfLeaves; ++i)
leaf_order.emplace_back(i-numIntComp);
for (size_t i = numOfLeaves - 1; i < numOfFullLeaves - 1 ; ++i)
leaf_order.emplace_back(i-numIntComp);
INTERNAL_CHECK(_me.tensorObject->nodes.size() == numNodes, "Internal Error.");
// Reset to new external links
for(size_t i = 0; i < numOfLeaves; ++i) {
_me.tensorObject->externalLinks[i].other = i+numIntComp;
_me.tensorObject->externalLinks[i].indexPosition = 1;
size_t ii = 0;
for(size_t i : leaf_order) {
_me.tensorObject->externalLinks[ii].other = i+numIntComp;
_me.tensorObject->externalLinks[ii].indexPosition = 1;
ii++;
}
if(isOperator) {
for(size_t i = 0; i < numOfLeaves; ++i) {
_me.tensorObject->externalLinks[numOfLeaves+i].other = i+numIntComp;
_me.tensorObject->externalLinks[numOfLeaves+i].indexPosition = 2;
ii = 0;
for(size_t i : leaf_order) {
_me.tensorObject->externalLinks[numOfLeaves+ii].other = i+numIntComp;
_me.tensorObject->externalLinks[numOfLeaves+ii].indexPosition = 2;
ii++;
}
}
// Fix the virtual node
_me.tensorObject->nodes[numNodes-1].tensorObject->reinterpret_dimensions({1});
_me.tensorObject->nodes[numNodes-1].neighbors.resize(1);
......@@ -356,13 +369,8 @@ namespace xerus {
std::vector<size_t> shuffle_leaves(N + stackSize);
for (size_t i = numIntComp; i < numNodes - 1; ++i) {
size_t parentCount = 0, parentDim = 1, fullDim = 1;
//Dummy components
if(i >= numComponents){
_me.tensorObject->nodes[i].tensorObject->reinterpret_dimensions({1});
_me.tensorObject->nodes[i].neighbors.resize(1);
_me.tensorObject->nodes[i].neighbors.front().other = (i-1)/2;
_me.tensorObject->nodes[i].neighbors.front().indexPosition = (i-1)%2 + 1;
} else {
std::vector<size_t>::iterator itr = std::find(leaf_order.begin(), leaf_order.end(), i - numIntComp);
size_t leaf_order_pos = static_cast<size_t>(std::distance(leaf_order.begin(), itr));
for(size_t k = 0; k < N + stackSize; ++k) {
INTERNAL_CHECK(!_me.tensorObject->nodes[i].erased, "IE");
const TensorNetwork::Link& link = _me.tensorObject->nodes[i].neighbors[k];
......@@ -381,26 +389,25 @@ namespace xerus {
parentDim *= link.dimension;
}
else
INTERNAL_CHECK(false, "Internal Error, something wrong with the links of the TTN");
INTERNAL_CHECK(false, "Internal Error, something wrong with the links of the HTN");
}
}
INTERNAL_CHECK(fullDim == _me.tensorObject->nodes[i].tensorObject->size, "Uhh");
INTERNAL_CHECK(parentCount == stackSize, "IE");
xerus::reshuffle(*_me.tensorObject->nodes[i].tensorObject, *_me.tensorObject->nodes[i].tensorObject, shuffle_leaves);
if(isOperator) {
_me.tensorObject->nodes[i].tensorObject->reinterpret_dimensions({parentDim, _me.tensorObject->dimensions[i - numIntComp], _me.tensorObject->dimensions[i - numIntComp+numOfLeaves]});
_me.tensorObject->nodes[i].tensorObject->reinterpret_dimensions({parentDim, _me.tensorObject->dimensions[leaf_order_pos], _me.tensorObject->dimensions[leaf_order_pos+numOfLeaves]});
} else {
_me.tensorObject->nodes[i].tensorObject->reinterpret_dimensions({parentDim, _me.tensorObject->dimensions[i - numIntComp]});
_me.tensorObject->nodes[i].tensorObject->reinterpret_dimensions({parentDim, _me.tensorObject->dimensions[leaf_order_pos]});
}
_me.tensorObject->nodes[i].neighbors.clear();
_me.tensorObject->nodes[i].neighbors.emplace_back( (i-1) / 2, i%2 == 1 ? 1:2, parentDim, false);
_me.tensorObject->nodes[i].neighbors.emplace_back(-1, i - numIntComp , _me.tensorObject->dimensions[i - numIntComp], true);
if(isOperator) { _me.tensorObject->nodes[i].neighbors.emplace_back(-1, numOfLeaves+i - numIntComp, _me.tensorObject->dimensions[numOfLeaves+i - numIntComp], true); }
}
_me.tensorObject->nodes[i].neighbors.emplace_back(-1, leaf_order_pos , _me.tensorObject->dimensions[leaf_order_pos], true);
if(isOperator) { _me.tensorObject->nodes[i].neighbors.emplace_back(-1, numOfLeaves+leaf_order_pos, _me.tensorObject->dimensions[leaf_order_pos+numOfLeaves], true); }
}
_me.tensorObject->require_valid_network();
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - Operator specializations - - - - - - - - - - - - - - - - - - - - - - - - - - */
......
......@@ -256,7 +256,8 @@ namespace xerus {
void TensorNetwork::sanitize() {
std::vector<size_t> idMap(nodes.size());
std::vector<size_t> idMap(nodes.size());
std::vector<size_t> oldNodes;
// Move nodes
size_t newId = 0, oldId = 0;
......@@ -265,20 +266,36 @@ namespace xerus {
idMap[oldId] = newId;
if (newId != oldId) { std::swap(nodes[newId], nodes[oldId]); }
newId++;
} else {
oldNodes.emplace_back(oldId);
}
}
// Update external links
for (TensorNetwork::Link &l : externalLinks) {
l.other = idMap[l.other];
}
// Update links
nodes.resize(newId);
size_t external_index_pos = externalLinks.size();
size_t count_nodes = 0;
for (TensorNode &n : nodes) {
size_t count_links = 0;
for (TensorNetwork::Link &l : n.neighbors) {
if (!l.external) { l.other = idMap[l.other]; }
bool new_external = std::find(oldNodes.begin(), oldNodes.end(), l.other) != oldNodes.end();
if (!l.external && !new_external) { l.other = idMap[l.other]; }
if (!l.external && new_external) {
l.other = -1;
l.indexPosition = external_index_pos;
external_index_pos++;
l.external = true;
externalLinks.emplace_back(count_nodes,count_links,l.dimension,false);
dimensions.emplace_back(l.dimension);
}
count_links++;
}
}
// Update external links
for (TensorNetwork::Link &l : externalLinks) {
l.other = idMap[l.other];
count_nodes++;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment