поэлементные операции с C++ повышения ublas матричные и типы векторов

Спецификация не ясна, поэтому мы просто догадываемся, чего мы пытаемся достичь.

Вот запрос, который удовлетворяет одной из возможных интерпретаций спецификации:

SELECT SUM(m.d1)
     , SUM(m.d2)
  FROM main m
 WHERE m.time1 >= ( SELECT MAX(s.time2) 
                      FROM secondary s 
                  )

Что подразумевается под «последней ячейкой»? Как нам определить строку из вторичной таблицы?

SELECT SUM(m.d1)
     , SUM(m.d2)
  FROM main m
 WHERE m.time1 >= ( SELECT s.time2 
                      FROM secondary s 
                     ORDER BY some_expression
                     LIMIT 1
                  )

Мы хотим вернуть только одну строку или мы хотим вернуть строку для каждой строки во вторичной таблице?

 SELECT s.time2 
      , ( SELECT SUM(m1.d1)
            FROM main m1
           WHERE m1.time1 >= s.time2
        ) AS tot_d1
      , ( SELECT SUM(m2.d2)
            FROM main m2
           WHERE m2.time1 >= s.time2
        ) AS tot_d2
   FROM secondary s
  ORDER BY s.time2 
7
задан jhofman 21 April 2009 в 17:26
поделиться

1 ответ

WARNING

The following answer is incorrect. See Edit at the bottom. I've left the original answer as is to give context and credit to those who pointed out the error.


I'm not particularly familiar with the boost libraries, so there may be a more standard way to do this, but I think you can do what you want with iterators and the STL transform function template. The introduction to the uBLAS library documentation says its classes are designed to be compatible with the same iterator behavior that is used in the STL. The boost matrix and vector templates all have iterators which can be used to access the individual elements. The vector has begin() and end(), and the matrix has begin1(), end1(), begin2(), and end2(). The 1 varieties are column-wise iterators and the 2 varieties are row-wise iterators. See the boost documentation on VectorExpression and MatrixExpression for a little more info.

Using the STL transform algorithm, you can apply a function to each element of an iterable sequence and assign the result to a different iterable sequence of the same length, or the same sequence. So to use this on a boost uBLAS vector you could do this:

using namespace boost::numeric::ublas;

// Create a 30 element vector of doubles
vector<double> vec(30);

// Assign 8.0 to each element.
std::fill(vec.begin(), vec.end(), 8.0);

// Perform the "Gamma" function on each element and assign the result back
// to the original element in the vector.
std::transform(vec.begin(), vec.end(), vec.begin(), boost::math::tgamma);

For a matrix it would be basically the same thing, you would use either the 1 or 2 family of iterators. Which one you choose to use depends on whether the memory layout of your matrix is row major or column major. A cursory scan of the uBLAS documentation leads me to believe that it could be either one, so you will need to examine the code and determine which one is being used so you choose the most efficient iteration order.

matrix<double> mat(30, 30);
.
.
.

std::transform(mat.begin1(), mat.end1(), mat.begin1(), boost::math::tgamma);

The function you pass as the last argument can be a function taking a single double argument and returning a double value. It can also be a functor.

This is not exactly the same as the vectorization example you cited, but it seems like it should be pretty close to what you want.


EDIT

Looks like I should have tested my recommendation before making it. As has been pointed out by others, the '1' and '2' iterators only iterate along a single row / column of the matrix. The overview documentation in Boost is seriously misleading on this. It claims that begin1() "Returns a iterator1 pointing to the beginning of the matrix" and that end1() "Returns a iterator1 pointing to the end of the matrix". Would it have killed them to say "a column of the matrix" instead of "matrix"? I assumed that an iterator1 was a column-wise iterator that would iterate over the whole matrix. For the correct way to do this, see Lantern Rouge's answer.

3
ответ дан 6 December 2019 в 21:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: