107 if (!a1 || a1->rank()==0 || !a2 || a2->rank()==0 || a1->hypercube()==a2->hypercube())
112 auto pivotArg1=make_shared<Pivot>(), pivotArg2=make_shared<Pivot>();
113 pivotArg1->setArgument(a1,{});
114 pivotArg2->setArgument(a2,{});
117 for (
auto& xv: a2->hypercube().xvectors) a2Axes.insert(xv.name);
120 std::vector<string> a1Order, common;
121 Hypercube hcSpread1, hcSpread2;
122 for (
auto& i: a1->hypercube().xvectors)
123 if (a2Axes.contains(i.name))
125 common.push_back(i.name);
126 a2Axes.erase(i.name);
130 a1Order.push_back(i.name);
131 hcSpread2.xvectors.push_back(i);
133 for (
auto& xv: a2->hypercube().xvectors)
134 if (a2Axes.contains(xv.name))
135 hcSpread1.xvectors.push_back(xv);
136 const size_t numCommonAxes=common.size();
139 a1Order.insert(a1Order.end(), common.begin(), common.end());
140 pivotArg1->setOrientation(a1Order);
142 common.insert(common.end(), a2Axes.begin(), a2Axes.end());
143 pivotArg2->setOrientation(common);
146 auto spread1=make_shared<SpreadLast>();
147 spread1->setArgument(pivotArg1,{});
148 spread1->setSpreadDimensions(hcSpread1);
149 auto spread2=make_shared<SpreadFirst>();
150 spread2->setArgument(pivotArg2,{});
151 spread2->setSpreadDimensions(hcSpread2);
155 auto& xv1=spread1->hypercube().xvectors;
156 auto& xv2=spread2->hypercube().xvectors;
157 assert(xv1.size()==xv2.size());
158 for (
size_t i=0; i<xv1.size(); ++i)
160 assert(xv1[i].name==xv2[i].name);
161 assert(xv1[i].dimension.type==xv2[i].dimension.type);
166 if (spread1->hypercube()==spread2->hypercube())
170 map<size_t,set<size_t>> p2i;
171 auto& xv=pivotArg2->hypercube().xvectors;
172 size_t commonElements=1;
173 for (
size_t i=0; i<numCommonAxes; ++i) commonElements*=xv[i].
size();
174 const size_t p1NumElements=pivotArg1->hypercube().numElements();
175 const size_t p1ExtraElements=p1NumElements/commonElements;
176 const size_t p2ExtraElements=pivotArg2->hypercube().numElements()/commonElements;
177 for (
auto i: pivotArg2->index())
180 auto r=lldiv(i,commonElements);
181 p2i[r.rem].insert(r.quot);
184 for (
auto i: pivotArg1->index())
185 for (
size_t j=0; j<p2ExtraElements; ++j)
188 auto s=p2i.find(i/p1ExtraElements);
190 if (
s->second.contains(j))
191 index.insert(i+p1NumElements*j);
197 Hypercube unionHC=spread1->hypercube();
198 civita::unionHypercube(unionHC,spread2->hypercube());
202 if (unionHC!=spread1->hypercube())
204 auto interpolate=make_shared<PivotedInterpolateHC>();
205 interpolate->hypercube(unionHC);
206 interpolate->setArgument(spread1,{});
209 if (unionHC!=spread2->hypercube())
211 auto interpolate=make_shared<PivotedInterpolateHC>();
212 interpolate->hypercube(unionHC);
213 interpolate->setArgument(spread2,{});
virtual const Index & index() const
the index vector - assumed to be ordered and unique
virtual std::size_t size() const
return number of elements in tensor - maybe less than hypercube.numElements if sparse ...
void setArguments(const TensorPtr &a1, const TensorPtr &a2, const ITensor::Args &args={"", 0}) override
void setArguments(const TensorPtr &a1, const TensorPtr &a2, const ITensor::Args &) override
std::shared_ptr< ITensor > TensorPtr