From: Paul Smyth <paul.smyth@vi...>  20030616 14:43:35

Hi folks again, please excuse the verbosity. I'm proposing some changes to vnl_vector_fixed_ref and vnl_matrix_fixed_ref to make them more efficient and flexible. History  I had a number of functions which interpreted blocks of memory as fixedsize vectors or matrices, and passed them to other functions which operated on the fixedsize vector/matrix references. e.g. void AngleAxisToRotationMatrix(const vnl_vector_fixed_ref<double,3> & AngleAxis, vnl_matrix_fixed<double,3,3> & RotationMatrix); double MyObjectiveFunction(const vnl_vector<double> & Params) { vnl_matrix_fixed<double,3,3> R; // I know that params 3,4,5 are rotation vnl_vector_fixed_ref<double,3> ref(const_cast<double*>& Params[3]); // interpret elems 3,4,5 of Params as a rotation AngleAxisToRotationMatrix(ref, R); // fill out rotation matrix from angleaxis parameterisation } As (until about 1 year ago) vector_fixed was derived from vector_fixed_ref, the above function could be used with _either_ vnl_vector_fixed_ref or vnl_vector_fixed as 1st argument. This could also be rather slow for matrices, as a set of unnecessary row pointers were calculated whenever the ref was constructed. e.g. void SimpleUsage() { vnl_matrix_fixed<double,3,3> R; vnl_vector_fixed<double,3> rot; AngleAxisToRotationMatrix(rot, R); } Then vector_fixed was (very sensibly) broken away from the rest of the heirarchy, which meant my code no longer compiled. Problem  I would like a number of algorithms that use fixedsize vectors/matrices to work with either referencestomemory or with 'true' vector/matrix_fixed. Proposal  1) Make standalone fixed_ref classes which don't drag in the rest of the vector/matrix heirarchy, as at present, and only contain a pointer, and can therefore be copied efficiently. So these are smart pointers, with compiletime size info. 2) Wherever fixed_ref classes to be used, pass them by value (or if necessary const reference), so that conversions from true vector_fixed can be applied. 3) Make separate fixed_ref and fixed_ref_const classes which preserve constness properly in the type. Note that vec_fixed_ref can only be constructed from (vec_fixed &), and vec_fixed_ref_const can be constructed from (vec_fixed const &). template <typename T, unsigned n> class vnl_vector_fixed_ref_const { const T* data_; public: vnl_vector_fixed_ref_const(vnl_vector_fixed<T,n> const & rhs); explicit vnl_vector_fixed_ref_const(const T * dataptr); ... }; template <typename T, unsigned n> class vnl_vector_fixed_ref { T* data_; public: explicit vnl_vector_fixed_ref(T * dataptr); vnl_vector_fixed_ref( vnl_vector_fixed<T,n> & rhs); ... }; New Usage: void AngleAxisToRotationMatrix(vnl_vector_fixed_ref_const<double,3> AngleAxis, vnl_matrix_fixed<double,3,3> & RotationMatrix); double MyObjectiveFunction(const vnl_vector<double> & Params) { vnl_matrix_fixed<double,3,3> R; // I know that params 3,4,5 are rotation vnl_vector_fixed_ref_const<double,3> ref(&Params[3]); // interpret elems 3,4,5 of Params as a rotation  no const_cast AngleAxisToRotationMatrix(ref, R); // fill out rotation matrix from angleaxis parameterisation } SimpleUsage() compiles unchanged. Comments:   I'd like to get something that enables me to interchange between *fixed_ref and *fixed committed, as current vxl doesn't support a whole batch of my code, and I want to get in sync. The above scheme works reasonably, and has been implemented.  Noone else (that I know of) except me uses *fixed_ref, so there is no code that will be broken.  A grander scheme would be possible for *_fixed_ref encoding more information (element,row,column stride) into the type which might aid fixedsize algorithms (see Addendum). I have a number of fast fixedsize routines operating this way that might be suitable for inclusion in vxl if this more elaborate scheme were used. But I could imagine its about 3 bridges too far. Paul. Addendum  A fancier scheme might take the form of: template <typename T, unsigned n, int element_stride> class vnl_vector_fixed_ref; template <typename T, unsigned n, int row_stride, int col_stride> class vnl_matrix_fixed_ref; which would enable references to be taken to noncontiguous memory. e.g. template <typename T, unsigned rows, unsigned cols> vnl_vector_fixed_ref<T,cols,1> vnl_matrix_fixed<T,rows,cols>::row_reference(unsigned col_index); // take reference to contiguous block of memory for a row template <typename T, unsigned rows, unsigned cols> vnl_vector_fixed_ref<T,rows,cols> vnl_matrix_fixed<T,rows,cols>::col_reference(unsigned col_index); // take reference to 'spliced' memory for a column template <typename T, unsigned rows, unsigned cols> vnl_matrix_fixed_ref<T,cols,rows,cols,1> vnl_matrix_fixed<T,rows,cols>::transpose_reference(); // view fixed matrix as its transpose This would enable a function like: template <typename T, unsigned r, unsigned c, int r_s, int c_s, int el_s1, int el_s2> void mat_vec_mult(matrix_fixed_ref_const<T,r,c,r_s,c_s> A, vector_fixed_ref_const<T,c,el_s1> x, vector_fixed_ref<T,c,el_s2> y) // perform y = A x: could be used to perform mulitplication of matrix transposed as well etc. etc. This email, and any attachment, is confidential. If you have received it in error, please delete it from your system, do not use or disclose the information in any way, and notify me immediately. 