26 #ifndef TILEDARRAY_SPECIALARRAYS_DIAGONAL_ARRAY_H__INCLUDED
27 #define TILEDARRAY_SPECIALARRAYS_DIAGONAL_ARRAY_H__INCLUDED
52 auto max_low = *std::max_element(lo, lo +
rank);
53 auto min_up = *std::min_element(up, up +
rank);
57 if (max_low < min_up) {
58 return Range({max_low}, {min_up});
74 auto diag_extent = *std::min_element(std::begin(ext), std::end(ext));
76 auto ndim = trange.
rank();
80 while (diag_elem < diag_extent) {
82 auto tile_idx = trange.
element_to_tile(std::vector<int>(ndim, diag_elem));
90 float t_norm = std::sqrt(val * val * d_range.volume());
91 shape(tile_idx) = t_norm;
94 diag_elem = d_range.upbound_data()[0];
108 template <
typename RandomAccessIterator>
109 std::enable_if_t<is_iterator<RandomAccessIterator>::value,
Tensor<float>>
111 RandomAccessIterator diagonals_end = {}) {
112 const bool have_end = diagonals_end == RandomAccessIterator{};
118 auto diag_extent = *std::min_element(ext, ext +
rank);
120 auto ndim = trange.
rank();
121 auto diag_elem = 0ul;
124 while (diag_elem < diag_extent) {
126 auto tile_idx = trange.
element_to_tile(std::vector<int>(ndim, diag_elem));
132 TA_ASSERT(diag_elem == d_range.lobound_data()[0]);
133 const auto beg = diag_elem;
134 const auto end = d_range.upbound_data()[0];
136 TA_ASSERT(diagonals_begin + beg < diagonals_end);
137 TA_ASSERT(diagonals_begin + end <= diagonals_end);
140 auto t_norm = std::accumulate(diagonals_begin + beg, diagonals_begin + end,
141 0.0, [](
const auto &
sum,
const auto &val) {
143 return sum + abs_val * abs_val;
145 shape(tile_idx) =
static_cast<float>(t_norm);
160 template <
typename Array,
typename T>
172 if (diags.volume() > 0) {
175 auto diag_lo = diags.lobound_data()[0];
176 auto diag_hi = diags.upbound_data()[0];
177 for (
auto elem = diag_lo; elem < diag_hi; ++elem) {
178 tile(std::vector<int>(
rank, elem)) = val;
192 template <
typename Array,
typename RandomAccessIterator>
193 std::enable_if_t<is_iterator<RandomAccessIterator>::value,
void>
199 [diagonals_begin](
const Range &rng) {
206 if (diags.volume() > 0) {
208 auto diag_lo = diags.lobound_data()[0];
209 auto diag_hi = diags.upbound_data()[0];
210 for (
auto elem = diag_lo; elem < diag_hi; ++elem) {
211 tile(std::vector<int>(
rank, elem)) = *(diagonals_begin + elem);
229 template <
typename Array,
typename T =
double>
233 if constexpr (is_dense_v<Policy>) {
234 Array A(world, trange);
240 using ShapeType =
typename Policy::shape_type;
241 ShapeType shape(shape_norm, trange);
242 Array A(world, trange, shape);
260 template <
typename Array,
typename RandomAccessIterator>
261 std::enable_if_t<detail::is_iterator<RandomAccessIterator>::value,
Array>
263 RandomAccessIterator diagonals_begin,
264 RandomAccessIterator diagonals_end = {}) {
267 if (diagonals_end != RandomAccessIterator{}) {
270 [[maybe_unused]]
auto diag_extent = *std::min_element(ext, ext +
rank);
271 TA_ASSERT(diagonals_begin + diag_extent <= diagonals_end);
275 if constexpr (is_dense_v<Policy>) {
276 Array A(world, trange);
283 using ShapeType =
typename Policy::shape_type;
284 ShapeType shape(shape_norm, trange);
285 Array A(world, trange, shape);
294 #endif // TILEDARRAY_SPECIALARRAYS_DIAGONAL_ARRAY_H__INCLUDED