Actions

icon Post
text/html Subscribe
text/html Unsubscribe

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[selgen]


  • To: vsipl++@xxxxxxxxxxxxxxxx
  • Subject: [selgen]
  • From: Stefan Seefeld <stefan@xxxxxxxxxxxxxxxx>
  • Date: Tue, 27 Sep 2005 16:40:42 -0400

The attached patch implements all functions from section 9.4 ([selgen])
of the spec, i.e.

* first()
* indexbool()
* gather()
* scatter()
* clip()
* invclip()
* swap()

together with unit tests. It also contains some bits and pieces I
submitted earlier today to cleanup header dependencies etc., as I
wasn't able to easily separate the two.

Regards,
		Stefan
Index: src/vsip/dense.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/dense.hpp,v
retrieving revision 1.28
diff -u -r1.28 dense.hpp
--- src/vsip/dense.hpp	16 Sep 2005 21:51:08 -0000	1.28
+++ src/vsip/dense.hpp	27 Sep 2005 20:36:01 -0000
@@ -23,7 +23,6 @@
 #include <vsip/impl/layout.hpp>
 #include <vsip/impl/extdata.hpp>
 #include <vsip/impl/block-traits.hpp>
-#include <vsip/impl/view_traits.hpp>
 #include <vsip/impl/point.hpp>
 
 /// Complex storage format for dense blocks.
Index: src/vsip/matrix.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/matrix.hpp,v
retrieving revision 1.26
diff -u -r1.26 matrix.hpp
--- src/vsip/matrix.hpp	16 Sep 2005 22:03:20 -0000	1.26
+++ src/vsip/matrix.hpp	27 Sep 2005 20:36:01 -0000
@@ -40,11 +40,9 @@
 {
 
 /// View which appears as a two-dimensional, read-only matrix.
-template <typename T = VSIP_DEFAULT_VALUE_TYPE,
-	  typename Block = Dense<2, T> >
-class const_Matrix :
-  public impl::Non_assignable,
-  public  vsip::impl_const_View<vsip::const_Matrix,Block>
+template <typename T, typename Block>
+class const_Matrix : public impl::Non_assignable,
+		     public  vsip::impl_const_View<vsip::const_Matrix,Block>
 {
   typedef vsip::impl_const_View<vsip::const_Matrix,Block> impl_base_type;
   typedef typename impl::Lvalue_factory_type<Block>::type impl_factory_type;
@@ -156,10 +154,8 @@
 /// inherits from const_Matrix, so only the members that const_Matrix
 /// does not carry, or that are different, need be specified.
 
-template <typename T = VSIP_DEFAULT_VALUE_TYPE,
-	  typename Block = Dense<2, T> >
-class Matrix : 
-  public vsip::impl_View<vsip::Matrix,Block>
+template <typename T, typename Block>
+class Matrix : public vsip::impl_View<vsip::Matrix,Block>
 {
   typedef vsip::impl_View<vsip::Matrix,Block> impl_base_type;
   typedef typename impl::Lvalue_factory_type<Block>::type impl_factory_type;
@@ -374,6 +370,20 @@
   static bool const value = true;
 };
 
+template <typename T, typename Block>
+T
+get(const_Matrix<T, Block> view, Index<2> const &i)
+{
+  return view.get(i[0], i[1]);
+}
+
+template <typename T, typename Block>
+void
+put(Matrix<T, Block> view, Index<2> const &i, T value)
+{
+  view.put(i[0], i[1], value);
+}
+
 } // namespace vsip::impl
 
 } // namespace vsip
Index: src/vsip/selgen.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/selgen.hpp,v
retrieving revision 1.1
diff -u -r1.1 selgen.hpp
--- src/vsip/selgen.hpp	26 Sep 2005 20:23:29 -0000	1.1
+++ src/vsip/selgen.hpp	27 Sep 2005 20:36:01 -0000
@@ -1,7 +1,7 @@
 /* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/selgen.hpp
-    @author  Jules Bergmann
+    @author  Jules Bergmann, Stefan Seefeld
     @date    2005-08-15
     @brief   VSIPL++ Library: Selection functions.
 
@@ -15,9 +15,10 @@
 ***********************************************************************/
 
 #include <vsip/impl/block-traits.hpp>
+#include <vsip/impl/expr_unary_block.hpp>
 #include <vsip/impl/expr_generator_block.hpp>
 #include <vsip/vector.hpp>
-
+#include <vsip/matrix.hpp>
 
 
 /***********************************************************************
@@ -30,6 +31,29 @@
 namespace impl
 {
 
+template <typename T, typename B1, typename B2>
+length_type
+indexbool(const_Vector<T, B1> source, Vector<Index<1>, B2> indices)
+{
+  index_type cursor = 0;
+  for (index_type i = 0; i != source.size(); ++i)
+    if (source.get(i))
+      indices.put(cursor++, Index<1>(i));
+  return cursor;
+}
+
+template <typename T, typename B1, typename B2>
+length_type
+indexbool(const_Matrix<T, B1> source, Vector<Index<2>, B2> indices)
+{
+  index_type cursor = 0;
+  for (index_type r = 0; r != source.size(0); ++r)
+    for (index_type c = 0; c != source.size(1); ++c)
+      if (source.get(r, c))
+	indices.put(cursor++, Index<2>(r, c));
+  return cursor;
+}
+
 /// Generator functor for ramp.
 
 template <typename T>
@@ -59,7 +83,56 @@
 
 } // namespace vsip::impl
 
+template <typename Predicate,
+	  typename T1, typename T2,
+	  typename B1, typename B2>
+index_type
+first(index_type begin, Predicate p, 
+      const_Vector<T1, B1> v, const_Vector<T2, B2> w) VSIP_NOTHROW
+{
+  assert(impl::view_domain(v).element_conformant(impl::view_domain(w)));
+  if (begin > v.size()) 
+    return begin;
+  for (index_type i = begin, end = v.size(); i != end; ++i)
+    if (p(v.get(i), w.get(i)))
+      return i;
+  return v.size();
+}
+
+template <template <typename, typename> class const_View,
+	  typename T, typename B1, typename B2>
+length_type
+indexbool(const_View<T, B1> source, 
+	  Vector<Index<const_View<T, B2>::dim>, B2> indices)
+VSIP_NOTHROW
+{
+  return impl::indexbool(source, indices);
+}
+
+template <template <typename, typename> class const_View,
+	  typename T, typename B1, typename B2>
+Vector<T, Dense<1, T> >
+gather(const_View<T, B1> source,
+       const_Vector<Index<const_View<T, B2>::dim>, B2> indices)
+VSIP_NOTHROW
+{
+  Vector<T, Dense<1, T> > result(indices.size());
+  for (index_type i = 0; i != indices.size(); ++i)
+    result.put(i, get(source, indices.get(i)));
+  return result;
+}
 
+template <template <typename, typename> class View,
+	  typename T, typename B1, typename B2, typename B3>
+void
+scatter(const_Vector<T, B1> source,
+	const_Vector<Index<View<T, B3>::dim>, B2>  indices,
+	View<T, B3> destination)
+VSIP_NOTHROW
+{
+  for (index_type i = 0; i != indices.size(); ++i)
+    put(destination, indices.get(i), source.get(i));
+}
 
 /// Generate a linear ramp.
 
@@ -85,6 +158,126 @@
   return const_Vector<T, block_type>(block);
 }
 
+namespace impl
+{
+template <typename Tout, typename Tin1>
+struct clip_wrapper
+{
+  template <typename Tin0>
+  struct clip_functor
+  {
+    typedef Tout result_type;
+    result_type operator()(Tin0 t) const 
+    {
+      return t <= lower_threshold ? lower_clip_value 
+	: t < upper_threshold ? t
+	: upper_clip_value;
+    }
+
+    Tin1 lower_threshold;
+    Tin1 upper_threshold;
+    result_type lower_clip_value;
+    result_type upper_clip_value;
+  };
+  template <typename Tin0>
+  struct invclip_functor
+  {
+    typedef Tout result_type;
+    result_type operator()(Tin0 t) const 
+    {
+      return t < lower_threshold ? t
+	: t < middle_threshold ? lower_clip_value
+	: t <= upper_threshold ? upper_clip_value
+	: t;
+    }
+
+    Tin1 lower_threshold;
+    Tin1 middle_threshold;
+    Tin1 upper_threshold;
+    result_type lower_clip_value;
+    result_type upper_clip_value;
+  };
+};
+  
+}
+
+template <typename Tout, typename Tin0, typename Tin1,
+	  template <typename, typename> class const_View,
+	  typename Block>
+const_View<Tout,
+  impl::Unary_expr_block<const_View<Tin0, Block>::dim,
+			 impl::clip_wrapper<Tout, Tin1>::template clip_functor,
+			 Block, Tin0> const>
+clip(const_View<Tin0, Block> v, Tin1 lower_threshold, Tin1 upper_threshold,
+     Tout lower_clip_value, Tout upper_clip_value)
+{
+  typedef impl::Unary_expr_block<const_View<Tin0, Block>::dim,
+    impl::clip_wrapper<Tout, Tin1>::template clip_functor,
+    Block, Tin0> block_type;
+
+  typename impl::clip_wrapper<Tout, Tin1>::template clip_functor<Tin0> functor;
+  functor.lower_threshold = lower_threshold;
+  functor.upper_threshold = upper_threshold;
+  functor.lower_clip_value = lower_clip_value;
+  functor.upper_clip_value = upper_clip_value;
+
+  return const_View<Tout, block_type const>(block_type(v.block(), functor));
+}
+
+template <typename Tout, typename Tin0, typename Tin1,
+	  template <typename, typename> class const_View,
+	  typename Block>
+const_View<Tout,
+  impl::Unary_expr_block<const_View<Tin0, Block>::dim,
+			 impl::clip_wrapper<Tout, Tin1>::template invclip_functor,
+			 Block, Tin0> const>
+invclip(const_View<Tin0, Block> v,
+	Tin1 lower_threshold, Tin1 middle_threshold, Tin1 upper_threshold,
+	Tout lower_clip_value, Tout upper_clip_value)
+{
+  typedef impl::Unary_expr_block<const_View<Tin0, Block>::dim,
+    impl::clip_wrapper<Tout, Tin1>::template invclip_functor,
+    Block, Tin0> block_type;
+
+  typename impl::clip_wrapper<Tout, Tin1>::template invclip_functor<Tin0> functor;
+  functor.lower_threshold = lower_threshold;
+  functor.middle_threshold = middle_threshold;
+  functor.upper_threshold = upper_threshold;
+  functor.lower_clip_value = lower_clip_value;
+  functor.upper_clip_value = upper_clip_value;
+
+  return const_View<Tout, block_type const>(block_type(v.block(), functor));
+}
+
+namespace impl
+{
+/// Generic swapping of the content of two blocks.
+template <typename Block1, typename Block2>
+struct Swap
+{
+  static void apply(Block1 &block1, Block2 &block2)
+  {
+    assert(block1.size() == block2.size());
+    for (index_type i = 0; i != block1.size(); ++i)
+    {
+      typename Block1::value_type tmp = block1.get(i);
+      block1.put(i, block2.get(i));
+      block2.put(i, tmp);
+    }
+
+  }
+};
+}
+
+template <typename T1, typename T2,
+	  template <typename, typename> class View,
+	  typename Block1, typename Block2>
+inline void
+swap(View<T1, Block1> v, View<T2, Block2> w)
+{
+  impl::Swap<Block1, Block2>::apply(v.block(), w.block());
+}
+
 } // namespace vsip
 
 #endif // VSIP_SELGEN_HPP
Index: src/vsip/tensor.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/tensor.hpp,v
retrieving revision 1.19
diff -u -r1.19 tensor.hpp
--- src/vsip/tensor.hpp	16 Sep 2005 22:03:20 -0000	1.19
+++ src/vsip/tensor.hpp	27 Sep 2005 20:36:01 -0000
@@ -42,11 +42,9 @@
 enum whole_domain_type { whole_domain};
 
 /// View which appears as a three-dimensional, read-only tensor.
-template <typename T = VSIP_DEFAULT_VALUE_TYPE,
-	  typename Block = Dense<3, T> >
-class const_Tensor :
-  public impl::Non_assignable,
-  public  vsip::impl_const_View<vsip::const_Tensor,Block>
+template <typename T, typename Block>
+class const_Tensor : public impl::Non_assignable,
+		     public  vsip::impl_const_View<vsip::const_Tensor,Block>
 {
   typedef vsip::impl_const_View<vsip::const_Tensor,Block> impl_base_type;
   typedef typename impl::Lvalue_factory_type<Block>::type impl_factory_type;
@@ -263,8 +261,7 @@
 /// inherits from const_Tensor, so only the members that const_Tensor
 /// does not carry, or that are different, need be specified.
 
-template <typename T = VSIP_DEFAULT_VALUE_TYPE,
-	  typename Block = Dense<3, T> >
+template <typename T, typename Block>
 class Tensor : public vsip::impl_View<vsip::Tensor, Block>
 {
   typedef vsip::impl_View<vsip::Tensor, Block> impl_base_type;
@@ -604,6 +601,20 @@
   static bool const value = true;
 };
 
+template <typename T, typename Block>
+T
+get(const_Tensor<T, Block> view, Index<3> const &i)
+{
+  return view.get(i[0], i[1], i[2]);
+}
+
+template <typename T, typename Block>
+void
+put(Tensor<T, Block> view, Index<3> const &i, T value)
+{
+  view.put(i[0], i[1], i[2], value);
+}
+
 } // namespace vsip::impl
 
 } // namespace vsip
Index: src/vsip/vector.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/vector.hpp,v
retrieving revision 1.31
diff -u -r1.31 vector.hpp
--- src/vsip/vector.hpp	26 Sep 2005 20:11:05 -0000	1.31
+++ src/vsip/vector.hpp	27 Sep 2005 20:36:02 -0000
@@ -39,11 +39,9 @@
 {
 
 /// View which appears as a one-dimensional, read-only vector.
-template <typename T = VSIP_DEFAULT_VALUE_TYPE,
-	  typename Block = Dense<1, T> >
-class const_Vector :
-	public impl::Non_assignable,
-	public vsip::impl_const_View<vsip::const_Vector,Block>
+template <typename T, typename Block>
+class const_Vector : public impl::Non_assignable,
+		     public vsip::impl_const_View<vsip::const_Vector,Block>
 {
   typedef vsip::impl_const_View<vsip::const_Vector,Block> impl_base_type;
   typedef typename impl::Lvalue_factory_type<Block>::type impl_factory_type;
@@ -156,8 +154,7 @@
 /// inherits from const_Vector, so only the members that const_Vector
 /// does not carry, or that are different, need be specified.
 
-template <typename T = VSIP_DEFAULT_VALUE_TYPE,
-	  typename Block = Dense<1, T> >
+template <typename T, typename Block>
 class Vector : public vsip::impl_View<vsip::Vector,Block>
 {
   typedef vsip::impl_View<vsip::Vector,Block> impl_base_type;
@@ -321,7 +318,19 @@
   static bool const value = true;
 };
 
+template <typename T, typename Block>
+T
+get(const_Vector<T, Block> view, Index<1> const &i)
+{
+  return view.get(i[0]);
+}
 
+template <typename T, typename Block>
+void
+put(Vector<T, Block> view, Index<1> const &i, T value)
+{
+  view.put(i[0], value);
+}
 
 // Return the view extent as a domain.
 
Index: src/vsip/impl/expr_functor.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/expr_functor.hpp,v
retrieving revision 1.6
diff -u -r1.6 expr_functor.hpp
--- src/vsip/impl/expr_functor.hpp	15 Sep 2005 14:49:25 -0000	1.6
+++ src/vsip/impl/expr_functor.hpp	27 Sep 2005 20:36:02 -0000
@@ -18,6 +18,7 @@
 #include <vsip/impl/expr_unary_block.hpp>
 #include <vsip/impl/expr_binary_block.hpp>
 #include <vsip/impl/expr_ternary_block.hpp>
+#include <vsip/impl/expr_binary_operators.hpp>
 
 namespace vsip
 {
Index: src/vsip/impl/matvec.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/matvec.hpp,v
retrieving revision 1.1
diff -u -r1.1 matvec.hpp
--- src/vsip/impl/matvec.hpp	19 Sep 2005 21:06:46 -0000	1.1
+++ src/vsip/impl/matvec.hpp	27 Sep 2005 20:36:02 -0000
@@ -17,6 +17,8 @@
 
 #include <vsip/vector.hpp>
 #include <vsip/matrix.hpp>
+#include <vsip/impl/promote.hpp>
+#include <vsip/impl/fns_elementwise.hpp>
 
 
 namespace vsip
Index: src/vsip/impl/view_traits.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/view_traits.hpp,v
retrieving revision 1.9
diff -u -r1.9 view_traits.hpp
--- src/vsip/impl/view_traits.hpp	28 Aug 2005 00:22:39 -0000	1.9
+++ src/vsip/impl/view_traits.hpp	27 Sep 2005 20:36:02 -0000
@@ -15,6 +15,7 @@
 ***********************************************************************/
 
 #include <vsip/support.hpp>
+#include <vsip/dense.hpp>
 #include <vsip/impl/subblock.hpp>
 #include <complex>
 
@@ -51,12 +52,18 @@
 
 } // impl
 
-template <typename T, typename B> struct Vector;
-template <typename T, typename B> struct Matrix;
-template <typename T, typename B> struct Tensor;
-template <typename T, typename B> struct const_Vector;
-template <typename T, typename B> struct const_Matrix;
-template <typename T, typename B> struct const_Tensor;
+template <typename T = VSIP_DEFAULT_VALUE_TYPE,
+	  typename B = Dense<1, T> > struct Vector;
+template <typename T = VSIP_DEFAULT_VALUE_TYPE,
+	  typename B = Dense<2, T> > struct Matrix;
+template <typename T = VSIP_DEFAULT_VALUE_TYPE,
+	  typename B = Dense<3, T> > struct Tensor;
+template <typename T = VSIP_DEFAULT_VALUE_TYPE,
+	  typename B = Dense<1, T> > struct const_Vector;
+template <typename T = VSIP_DEFAULT_VALUE_TYPE,
+	  typename B = Dense<2, T> > struct const_Matrix;
+template <typename T = VSIP_DEFAULT_VALUE_TYPE,
+	  typename B = Dense<3, T> > struct const_Tensor;
 
 namespace impl
 {
Index: tests/test.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/test.hpp,v
retrieving revision 1.6
diff -u -r1.6 test.hpp
--- tests/test.hpp	23 Aug 2005 19:32:53 -0000	1.6
+++ tests/test.hpp	27 Sep 2005 20:36:02 -0000
@@ -16,8 +16,11 @@
 
 #include <cstdlib>
 
+#include <vsip/support.hpp>
 #include <vsip/complex.hpp>
-
+#include <vsip/vector.hpp>
+#include <vsip/matrix.hpp>
+#include <vsip/tensor.hpp>
 
 
 /***********************************************************************
@@ -119,7 +122,43 @@
          equal(val1.imag(), val2.imag());
 }
 
+template <typename T, typename Block1, typename Block2>
+inline bool
+view_equal(vsip::const_Vector<T, Block1> v, vsip::const_Vector<T, Block2> w)
+{
+  if (v.size() != w.size()) return false;
+  for (vsip::length_type i = 0; i != v.size(); ++i)
+    if (!equal(v.get(i), w.get(i)))
+      return false;
+  return true;
+}
 
+template <typename T, typename Block1, typename Block2>
+inline bool
+view_equal(vsip::const_Matrix<T, Block1> v, vsip::const_Matrix<T, Block2> w)
+{
+  if (v.size(0) != w.size(0) || v.size(1) != w.size(1)) return false;
+  for (vsip::length_type i = 0; i != v.size(0); ++i)
+    for (vsip::length_type j = 0; j != v.size(1); ++j)
+      if (!equal(v.get(i, j), w.get(i, j)))
+	return false;
+  return true;
+}
+
+template <typename T, typename Block1, typename Block2>
+inline bool
+view_equal(vsip::const_Tensor<T, Block1> v, vsip::const_Tensor<T, Block2> w)
+{
+  if (v.size(0) != w.size(0) ||
+      v.size(1) != w.size(1) ||
+      v.size(2) != w.size(2)) return false;
+  for (vsip::length_type i = 0; i != v.size(0); ++i)
+    for (vsip::length_type j = 0; j != v.size(1); ++j)
+      for (vsip::length_type k = 0; k != v.size(2); ++k)
+	if (!equal(v.get(i, j, k), w.get(i, j, k)))
+	  return false;
+  return true;
+}
 
 /// Use a variable.  Useful for tests that must create a variable but
 /// do not otherwise use it.