Index: boost/numeric/ublas/functional.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/numeric/ublas/functional.hpp,v
retrieving revision 1.30
diff -u -p -r1.30 functional.hpp
--- boost/numeric/ublas/functional.hpp	1 Jul 2005 20:08:54 -0000	1.30
+++ boost/numeric/ublas/functional.hpp	9 Jul 2005 19:57:22 -0000
@@ -1359,6 +1360,8 @@ namespace boost { namespace numeric { na
         static BOOST_UBLAS_INLINE
         result_type apply (const matrix_expression<E> &e) {
             real_type t = real_type ();
+#if 0
+            // This is inefficient for sparse types!
             size_type size2 (e ().size2 ());
             for (size_type j = 0; j < size2; ++ j) {
                 real_type u = real_type ();
@@ -1370,7 +1373,22 @@ namespace boost { namespace numeric { na
                 if (u > t)
                     t = u;
             }
-            return t; 
+#else
+            typename E::const_iterator1 it1 = e().begin1();
+            typename E::const_iterator1 const end1 = e().end1();
+            for (; it1 != end1; ++it1) {
+                real_type u = real_type();
+                typename E::const_iterator2 it2 = it1.begin();
+                typename E::const_iterator2 const end2 = it1.end();
+                for (; it2 != end2; ++it2) {
+                    real_type v(type_traits<value_type>::norm_1(*it2));
+                    u += v;
+                }
+                if (u > t)
+                    t = u;
+            }
+#endif
+            return t;
         }
     };
     template<class T>
@@ -1386,6 +1404,8 @@ namespace boost { namespace numeric { na
         static BOOST_UBLAS_INLINE
         result_type apply (const matrix_expression<E> &e) { 
             real_type t = real_type ();
+#if 0
+            // This is inefficient for sparse types!
             size_type size1 (e ().size1 ());
             for (size_type i = 0; i < size1; ++ i) {
                 size_type size2 (e ().size2 ());
@@ -1394,7 +1414,19 @@ namespace boost { namespace numeric { na
                     t +=  u * u;
                 }
             }
-            return type_traits<real_type>::sqrt (t); 
+#else
+            typename E::const_iterator1 it1 = e().begin1();
+            typename E::const_iterator1 const end1 = e().end1();
+            for (; it1 != end1; ++it1) {
+                typename E::const_iterator2 it2 = it1.begin();
+                typename E::const_iterator2 const end2 = it1.end();
+                for (; it2 != end2; ++it2) {
+                    real_type u(type_traits<value_type>::norm_2(*it2));
+                    t += u * u;
+                }
+            }
+#endif
+            return type_traits<real_type>::sqrt (t);
         }
     };
     template<class T>
@@ -1410,6 +1442,8 @@ namespace boost { namespace numeric { na
         static BOOST_UBLAS_INLINE
         result_type apply (const matrix_expression<E> &e) {
             real_type t = real_type ();
+#if 0
+            // This is inefficient for sparse types!
             size_type size1 (e ().size1 ());
             for (size_type i = 0; i < size1; ++ i) {
                 real_type u = real_type ();
@@ -1421,7 +1455,22 @@ namespace boost { namespace numeric { na
                 if (u > t) 
                     t = u;  
             }
-            return t; 
+#else
+            typename E::const_iterator1 it1 = e().begin1();
+            typename E::const_iterator1 const end1 = e().end1();
+            for (; it1 != end1; ++it1) {
+                real_type u = real_type();
+                typename E::const_iterator2 it2 = it1.begin();
+                typename E::const_iterator2 const end2 = it1.end();
+                for (; it2 != end2; ++it2) {
+                    real_type v(type_traits<value_type>::norm_inf(*it2));
+                    u += v;
+                }
+                if (u > t) 
+                    t = u;  
+            }
+#endif
+            return t;
         }
     };
 

