Boost logo

Ublas :

From: Gunter Winkler (guwi17_at_[hidden])
Date: 2006-02-13 08:44:36


On Friday 10 February 2006 13:17, Gunter Winkler wrote:
> Hello,
>
> I have the following problem:
>
> I have a pointer to a double array: const double *data;
> and an integer size
>
> I would like to use this as a vector in ublas routines.
>
> I expected that
>
> carray_adaptor<const double> shared(size, data);
> vector<const double, carray_adaptor<const double> > v(size, shared);
>
> does the job. Unfortunately it does not compile because the copy
> constructor of carray_adaptor is private. But this make the adaptor quite
> useless, because I am not able to convert it into a vector_expression
> (without copying the data).
>
> What is the rigth way to solve my problem?
>
> Should we support a syntax like
>
> vector<double> v(size);
> matrix<double> m(size, size);
> const double *external_data;
>
> v = prod(m, external_vector_adaptor(size, external_data));
>
> this would be very convenient.

I solved the above problem by modifying carray_adaptor. Should it be added
to storage.hpp and documented or should I provide a short sample program an put
it on webpage?

  template <class T>
  boost::numeric::ublas::vector<const T, boost::numeric::ublas::readonly_array_adaptor<T> >
  make_vector(const size_t dim, const T *data)
  {
    typedef boost::numeric::ublas::readonly_array_adaptor<T> a_t;
    typedef boost::numeric::ublas::vector<const T, a_t> v_t;
    a_t pa(dim, data);
    v_t v(dim, pa);
    return v;
  }

  /** \brief gives read only access to a chunk of memory.
   *
   * example:
   * <code>
   * T data[dim];
   * typedef readonly_array_adaptor<T> a_t;
   * typedef vector<const T, a_t> v_t;
   * a_t pa(dim, &(data[0]));
   * v_t v(dim, pa);
   * </code>
   */
    template<class T>
    class readonly_array_adaptor:
        public storage_array<readonly_array_adaptor<T> > {

        typedef readonly_array_adaptor<T> self_type;
    public:
        typedef std::size_t size_type;
        typedef std::ptrdiff_t difference_type;
        typedef T value_type;
        typedef const T &const_reference;
        typedef const T *const_pointer;
    public:

        // Construction and destruction
        BOOST_UBLAS_INLINE
        readonly_array_adaptor ():
            size_ (0), data_ (0) {
        }
        BOOST_UBLAS_INLINE
        readonly_array_adaptor (size_type size, const_pointer data):
            size_ (size), data_ (data) {
        }
        BOOST_UBLAS_INLINE
        ~readonly_array_adaptor () {
        }

        readonly_array_adaptor (const readonly_array_adaptor& rhs)
          : size_(rhs.size_), data_(rhs.data_)
        { }

        // Resizing
        BOOST_UBLAS_INLINE
        void resize (size_type size) {
            size_ = size;
        }
        BOOST_UBLAS_INLINE
        void resize (size_type size, const_pointer data) {
            size_ = size;
            data_ = data;
        }

        // Random Access Container
        BOOST_UBLAS_INLINE
        size_type max_size () const {
            return std::numeric_limits<size_type>::max ();
        }
        
        BOOST_UBLAS_INLINE
        bool empty () const {
            return size_ == 0;
        }
            
        BOOST_UBLAS_INLINE
        size_type size () const {
            return size_;
        }

        // Element access
        BOOST_UBLAS_INLINE
        const_reference operator [] (size_type i) const {
            BOOST_UBLAS_CHECK (i < size_, bad_index ());
            return data_ [i];
        }

        // Iterators simply are pointers.
        typedef const_pointer const_iterator;

        BOOST_UBLAS_INLINE
        const_iterator begin () const {
            return data_;
        }
        BOOST_UBLAS_INLINE
        const_iterator end () const {
            return data_ + size_;
        }

        // this typedef is used by vector and matrix classes
        typedef const_pointer iterator;

        // Reverse iterators
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
        typedef std::reverse_iterator<iterator> reverse_iterator;

        BOOST_UBLAS_INLINE
        const_reverse_iterator rbegin () const {
            return const_reverse_iterator (end ());
        }
        BOOST_UBLAS_INLINE
        const_reverse_iterator rend () const {
            return const_reverse_iterator (begin ());
        }

    private:
        size_type size_;
        const_pointer data_;
    };