File indexing completed on 2025-01-18 09:43:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef _BOOST_UBLAS_TENSOR_ALGORITHMS_HPP
0014 #define _BOOST_UBLAS_TENSOR_ALGORITHMS_HPP
0015
0016
0017 #include <stdexcept>
0018 #include <complex>
0019 #include <functional>
0020
0021 namespace boost {
0022 namespace numeric {
0023 namespace ublas {
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 template <class PointerOut, class PointerIn, class SizeType>
0040 void copy(const SizeType p, SizeType const*const n,
0041 PointerOut c, SizeType const*const wc,
0042 PointerIn a, SizeType const*const wa)
0043 {
0044 static_assert( std::is_pointer<PointerOut>::value & std::is_pointer<PointerIn>::value,
0045 "Static error in boost::numeric::ublas::copy: Argument types for pointers are not pointer types.");
0046 if( p == 0 )
0047 return;
0048
0049 if(c == nullptr || a == nullptr)
0050 throw std::length_error("Error in boost::numeric::ublas::copy: Pointers shall not be null pointers.");
0051
0052 if(wc == nullptr || wa == nullptr)
0053 throw std::length_error("Error in boost::numeric::ublas::copy: Pointers shall not be null pointers.");
0054
0055 if(n == nullptr)
0056 throw std::length_error("Error in boost::numeric::ublas::copy: Pointers shall not be null pointers.");
0057
0058
0059 std::function<void(SizeType r, PointerOut c, PointerIn a)> lambda;
0060
0061 lambda = [&lambda, n, wc, wa](SizeType r, PointerOut c, PointerIn a)
0062 {
0063 if(r > 0)
0064 for(auto d = 0u; d < n[r]; c += wc[r], a += wa[r], ++d)
0065 lambda(r-1, c, a );
0066 else
0067 for(auto d = 0u; d < n[0]; c += wc[0], a += wa[0], ++d)
0068 *c = *a;
0069 };
0070
0071 lambda( p-1, c, a );
0072 }
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089 template <class PointerOut, class PointerIn, class SizeType, class UnaryOp>
0090 void transform(const SizeType p,
0091 SizeType const*const n,
0092 PointerOut c, SizeType const*const wc,
0093 PointerIn a, SizeType const*const wa,
0094 UnaryOp op)
0095 {
0096 static_assert( std::is_pointer<PointerOut>::value & std::is_pointer<PointerIn>::value,
0097 "Static error in boost::numeric::ublas::transform: Argument types for pointers are not pointer types.");
0098 if( p == 0 )
0099 return;
0100
0101 if(c == nullptr || a == nullptr)
0102 throw std::length_error("Error in boost::numeric::ublas::transform: Pointers shall not be null pointers.");
0103
0104 if(wc == nullptr || wa == nullptr)
0105 throw std::length_error("Error in boost::numeric::ublas::transform: Pointers shall not be null pointers.");
0106
0107 if(n == nullptr)
0108 throw std::length_error("Error in boost::numeric::ublas::transform: Pointers shall not be null pointers.");
0109
0110
0111 std::function<void(SizeType r, PointerOut c, PointerIn a)> lambda;
0112
0113 lambda = [&lambda, n, wc, wa, op](SizeType r, PointerOut c, PointerIn a)
0114 {
0115 if(r > 0)
0116 for(auto d = 0u; d < n[r]; c += wc[r], a += wa[r], ++d)
0117 lambda(r-1, c, a);
0118 else
0119 for(auto d = 0u; d < n[0]; c += wc[0], a += wa[0], ++d)
0120 *c = op(*a);
0121 };
0122
0123 lambda( p-1, c, a );
0124
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 template <class PointerIn, class ValueType, class SizeType>
0139 ValueType accumulate(SizeType const p, SizeType const*const n,
0140 PointerIn a, SizeType const*const w,
0141 ValueType k)
0142 {
0143 static_assert(std::is_pointer<PointerIn>::value,
0144 "Static error in boost::numeric::ublas::transform: Argument types for pointers are not pointer types.");
0145
0146 if( p == 0 )
0147 return k;
0148
0149 if(a == nullptr)
0150 throw std::length_error("Error in boost::numeric::ublas::transform: Pointers shall not be null pointers.");
0151
0152 if(w == nullptr)
0153 throw std::length_error("Error in boost::numeric::ublas::transform: Pointers shall not be null pointers.");
0154
0155 if(n == nullptr)
0156 throw std::length_error("Error in boost::numeric::ublas::transform: Pointers shall not be null pointers.");
0157
0158
0159 std::function<ValueType(SizeType r, PointerIn a, ValueType k)> lambda;
0160
0161 lambda = [&lambda, n, w](SizeType r, PointerIn a, ValueType k)
0162 {
0163 if(r > 0u)
0164 for(auto d = 0u; d < n[r]; a += w[r], ++d)
0165 k = lambda(r-1, a, k);
0166 else
0167 for(auto d = 0u; d < n[0]; a += w[0], ++d)
0168 k += *a;
0169 return k;
0170 };
0171
0172 return lambda( p-1, a, k );
0173 }
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 template <class PointerIn, class ValueType, class SizeType, class BinaryOp>
0188 ValueType accumulate(SizeType const p, SizeType const*const n,
0189 PointerIn a, SizeType const*const w,
0190 ValueType k, BinaryOp op)
0191 {
0192 static_assert(std::is_pointer<PointerIn>::value,
0193 "Static error in boost::numeric::ublas::transform: Argument types for pointers are not pointer types.");
0194
0195
0196 if( p == 0 )
0197 return k;
0198
0199 if(a == nullptr)
0200 throw std::length_error("Error in boost::numeric::ublas::transform: Pointers shall not be null pointers.");
0201
0202 if(w == nullptr)
0203 throw std::length_error("Error in boost::numeric::ublas::transform: Pointers shall not be null pointers.");
0204
0205 if(n == nullptr)
0206 throw std::length_error("Error in boost::numeric::ublas::transform: Pointers shall not be null pointers.");
0207
0208
0209 std::function<ValueType(SizeType r, PointerIn a, ValueType k)> lambda;
0210
0211 lambda = [&lambda, n, w, op](SizeType r, PointerIn a, ValueType k)
0212 {
0213 if(r > 0u)
0214 for(auto d = 0u; d < n[r]; a += w[r], ++d)
0215 k = lambda(r-1, a, k);
0216 else
0217 for(auto d = 0u; d < n[0]; a += w[0], ++d)
0218 k = op ( k, *a );
0219 return k;
0220 };
0221
0222 return lambda( p-1, a, k );
0223 }
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 template <class PointerOut, class PointerIn, class SizeType>
0241 void trans( SizeType const p, SizeType const*const na, SizeType const*const pi,
0242 PointerOut c, SizeType const*const wc,
0243 PointerIn a, SizeType const*const wa)
0244 {
0245
0246 static_assert( std::is_pointer<PointerOut>::value & std::is_pointer<PointerIn>::value,
0247 "Static error in boost::numeric::ublas::trans: Argument types for pointers are not pointer types.");
0248
0249 if( p < 2)
0250 return;
0251
0252 if(c == nullptr || a == nullptr)
0253 throw std::runtime_error("Error in boost::numeric::ublas::trans: Pointers shall not be null pointers.");
0254
0255 if(na == nullptr)
0256 throw std::runtime_error("Error in boost::numeric::ublas::trans: Pointers shall not be null.");
0257
0258 if(wc == nullptr || wa == nullptr)
0259 throw std::length_error("Error in boost::numeric::ublas::trans: Pointers shall not be null pointers.");
0260
0261 if(na == nullptr)
0262 throw std::length_error("Error in boost::numeric::ublas::trans: Pointers shall not be null pointers.");
0263
0264 if(pi == nullptr)
0265 throw std::length_error("Error in boost::numeric::ublas::trans: Pointers shall not be null pointers.");
0266
0267
0268 std::function<void(SizeType r, PointerOut c, PointerIn a)> lambda;
0269
0270 lambda = [&lambda, na, wc, wa, pi](SizeType r, PointerOut c, PointerIn a)
0271 {
0272 if(r > 0)
0273 for(auto d = 0u; d < na[r]; c += wc[pi[r]-1], a += wa[r], ++d)
0274 lambda(r-1, c, a);
0275 else
0276 for(auto d = 0u; d < na[0]; c += wc[pi[0]-1], a += wa[0], ++d)
0277 *c = *a;
0278 };
0279
0280 lambda( p-1, c, a );
0281 }
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 template <class ValueType, class SizeType>
0300 void trans( SizeType const p,
0301 SizeType const*const na,
0302 SizeType const*const pi,
0303 std::complex<ValueType>* c, SizeType const*const wc,
0304 std::complex<ValueType>* a, SizeType const*const wa)
0305 {
0306 if( p < 2)
0307 return;
0308
0309 if(c == nullptr || a == nullptr)
0310 throw std::length_error("Error in boost::numeric::ublas::trans: Pointers shall not be null pointers.");
0311
0312 if(wc == nullptr || wa == nullptr)
0313 throw std::length_error("Error in boost::numeric::ublas::trans: Pointers shall not be null pointers.");
0314
0315 if(na == nullptr)
0316 throw std::length_error("Error in boost::numeric::ublas::trans: Pointers shall not be null pointers.");
0317
0318 if(pi == nullptr)
0319 throw std::length_error("Error in boost::numeric::ublas::trans: Pointers shall not be null pointers.");
0320
0321
0322 std::function<void(SizeType r, std::complex<ValueType>* c, std::complex<ValueType>* a)> lambda;
0323
0324 lambda = [&lambda, na, wc, wa, pi](SizeType r, std::complex<ValueType>* c, std::complex<ValueType>* a)
0325 {
0326 if(r > 0)
0327 for(auto d = 0u; d < na[r]; c += wc[pi[r]-1], a += wa[r], ++d)
0328 lambda(r-1, c, a);
0329 else
0330 for(auto d = 0u; d < na[0]; c += wc[pi[0]-1], a += wa[0], ++d)
0331 *c = std::conj(*a);
0332 };
0333
0334 lambda( p-1, c, a );
0335
0336 }
0337
0338
0339
0340
0341 }
0342 }
0343 }
0344
0345 #endif