0

I was looking at one of the answers to: filling a boost vector or matrix but I think I'm new to boost(and xcode, for that matter) and am trying to wrap my head around the boost zero_vector.

I tried a simple program that I thought was about the same as one of the answers:

#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>

int main (int argc, char * const argv[]) {
    // insert code here...
    using namespace boost::numeric::ublas;

    int gameSize = 9;

    typedef vector<int> possiblesVector;
    possiblesVector foo;
    foo.resize(gameSize);
    foo = zero_vector<int>(gameSize);
    std::cout << foo << std::endl;

    return 0;
}

which compiles, but when it runs, I get a runtime error (substituting "/PATH/TO" for the real path).

Check failed in file /PATH/TO/boost_1_48_0/boost/numeric/ublas/detail/vector_assign.hpp at line 370:
detail::expression_type_check (v, cv)
terminate called after throwing an instance of 'boost::numeric::ublas::external_logic'
  what():  external logic or bad condition of inputs
Program received signal:  “SIGABRT”.
sharedlibrary apply-load-rules all

Here, I'm just using a single main.cpp as a test area. In my real program, I have the declarations split into a .h file and my initializations in a .cpp file of my object. But the above code fails in the same way as my real program. (i.e. why I'm splitting declare and initialization into 2 steps)

Also, I know the resize already initializes to zero. Maybe I'll do a scalar_vector instead, or maybe I'll need to reset the array later on or something. I was just trying to isolate the code that is breaking.

Community
  • 1
  • 1
Steve Hwan
  • 459
  • 1
  • 6
  • 12
  • `using namespace boost::numeric::ublas;` bad practice ... `using namespace` are usually included in the top of the file, after the `#include` – cybertextron Jul 19 '12 at 01:38
  • 2
    @philippe: Uh, you've got that backwards. Keep `using`'s as local as possible. – GManNickG Jul 19 '12 at 01:42
  • @GManNickG But Why? If in the namespace there's a class you don't like, why don't you just include those classes you're going to use? – cybertextron Jul 19 '12 at 01:43
  • Why are you trying to do this: foo.resize(gameSize); foo = zero_vector(gameSize); std::cout << foo << std::endl; – cybertextron Jul 19 '12 at 01:45
  • @philippe: I don't understand your statements. Your first comment seems to object to the location of the using declaration, but your second seems to object to their use at all (I think?). Which is it? – GManNickG Jul 19 '12 at 01:46
  • First, I'm trying to figure out how to use a zero_vector. But I anticipate needing to reset my vector to a zero_vector now and then after adding stuff to foo. But I didn't need to add anything to it to demo the runtime error. – Steve Hwan Jul 19 '12 at 01:48
  • By the way, I also tried moving the using statement to above the main declaration, and it fails in the same way. I also tried removing it and explicitly declaring the namespaces for vector and zero_vector, and it fails in the same way as well. – Steve Hwan Jul 19 '12 at 01:49
  • You appear to be trying to use the BLAS zero_vector: http://www.boost.org/doc/libs/1_48_0/libs/numeric/ublas/doc/html/classboost_1_1numeric_1_1ublas_1_1zero__vector.html For a traditional STL std::vector. I've never used this library, but note that the example you reference uses a BLAS c_vector instead: boost::numeric::ublas::c_vector v; v = boost::numeric::ublas::zero_vector(N); – holtavolt Jul 19 '12 at 02:34
  • 1
    So, vector works fine, c_vector will fails. – ForEveR Jul 19 '12 at 02:40

1 Answers1

0
    template<template <class T1, class T2> class F, class V, class E>
    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    void vector_assign (V &v, const vector_expression<E> &e, sparse_tag) {
        BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
        typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
        BOOST_STATIC_ASSERT ((!functor_type::computed));
        typedef typename V::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
        vector<value_type> cv (v.size ());
        indexing_vector_assign<scalar_assign> (cv, v);
        indexing_vector_assign<F> (cv, e);
#endif
        v.clear ();
        typename E::const_iterator ite (e ().begin ());
        typename E::const_iterator ite_end (e ().end ());
        while (ite != ite_end) {
            value_type t (*ite);
            if (t != value_type/*zero*/())
                v.insert_element (ite.index (), t);
            ++ ite;
        }
#if BOOST_UBLAS_TYPE_CHECK
        if (! disable_type_check<bool>::value) 
            BOOST_UBLAS_CHECK (detail::expression_type_check (v, cv), 
                               external_logic ("external logic or bad condition of inputs"));
#endif
    }

where v is your vector<int> possiblesVector and e is temporary zero_vector<int>

// Weak equality check - useful to compare equality two arbitary vector expression results.
// Since the actual expressions are unknown, we check for and arbitary error bound
// on the relative error.
// For a linear expression the infinity norm makes sense as we do not know how the elements will be
// combined in the expression. False positive results are inevitable for arbirary expressions!
template<class E1, class E2, class S>
BOOST_UBLAS_INLINE
bool equals (const vector_expression<E1> &e1, const vector_expression<E2> &e2, S epsilon, S min_norm) {
    return norm_inf (e1 - e2) < epsilon *
           std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
}

template<class E1, class E2>
BOOST_UBLAS_INLINE
bool expression_type_check (const vector_expression<E1> &e1, const vector_expression<E2> &e2) {
    typedef typename type_traits<typename promote_traits<typename E1::value_type,
                                 typename E2::value_type>::promote_type>::real_type real_type;
    return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
}

check functions.

All elements of zero_vector is 0, so after

    v.clear ();
    typename E::const_iterator ite (e ().begin ());
    typename E::const_iterator ite_end (e ().end ());
    while (ite != ite_end) {
        value_type t (*ite);
        if (t != value_type/*zero*/())
            v.insert_element (ite.index (), t);
        ++ ite;
    }

vector v rest empty and check failed. Try to use double or float instead int.

ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • I didn't follow that last chunk. What do you mean "vector v rest empty"? I don't understand what int is doing. – Steve Hwan Jul 19 '12 at 16:09
  • @SteveHwan if (t != int /*zero*/()) { v.insert_element(ite.index(), t); } ++ite; Element will be inserted in vector if and only if current element not equal to int(), int() is zero. So... – ForEveR Jul 19 '12 at 16:54