Squashed 'third_party/boostorg/ublas/' content from commit e8607b3

Change-Id: Ia06afd642157a24e17fa9ddea28fb8601810b78e
git-subtree-dir: third_party/boostorg/ublas
git-subtree-split: e8607b3eea238e590eca93bfe498c21f470155c1
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..3e84d7c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,96 @@
+* text=auto !eol svneol=native#text/plain
+*.gitattributes text svneol=native#text/plain
+
+# Scriptish formats
+*.bat        text svneol=native#text/plain
+*.bsh        text svneol=native#text/x-beanshell
+*.cgi        text svneol=native#text/plain
+*.cmd        text svneol=native#text/plain
+*.js         text svneol=native#text/javascript
+*.php        text svneol=native#text/x-php
+*.pl         text svneol=native#text/x-perl
+*.pm         text svneol=native#text/x-perl
+*.py         text svneol=native#text/x-python
+*.sh         eol=lf svneol=LF#text/x-sh
+configure    eol=lf svneol=LF#text/x-sh
+
+# Image formats
+*.bmp        binary svneol=unset#image/bmp
+*.gif        binary svneol=unset#image/gif
+*.ico        binary svneol=unset#image/ico
+*.jpeg       binary svneol=unset#image/jpeg
+*.jpg        binary svneol=unset#image/jpeg
+*.png        binary svneol=unset#image/png
+*.tif        binary svneol=unset#image/tiff
+*.tiff       binary svneol=unset#image/tiff
+*.svg        text svneol=native#image/svg%2Bxml
+
+# Data formats
+*.pdf        binary svneol=unset#application/pdf
+*.avi        binary svneol=unset#video/avi
+*.doc        binary svneol=unset#application/msword
+*.dsp        text svneol=crlf#text/plain
+*.dsw        text svneol=crlf#text/plain
+*.eps        binary svneol=unset#application/postscript
+*.gz         binary svneol=unset#application/gzip
+*.mov        binary svneol=unset#video/quicktime
+*.mp3        binary svneol=unset#audio/mpeg
+*.ppt        binary svneol=unset#application/vnd.ms-powerpoint
+*.ps         binary svneol=unset#application/postscript
+*.psd        binary svneol=unset#application/photoshop
+*.rdf        binary svneol=unset#text/rdf
+*.rss        text svneol=unset#text/xml
+*.rtf        binary svneol=unset#text/rtf
+*.sln        text svneol=native#text/plain
+*.swf        binary svneol=unset#application/x-shockwave-flash
+*.tgz        binary svneol=unset#application/gzip
+*.vcproj     text svneol=native#text/xml
+*.vcxproj    text svneol=native#text/xml
+*.vsprops    text svneol=native#text/xml
+*.wav        binary svneol=unset#audio/wav
+*.xls        binary svneol=unset#application/vnd.ms-excel
+*.zip        binary svneol=unset#application/zip
+
+# Text formats
+.htaccess    text svneol=native#text/plain
+*.bbk        text svneol=native#text/xml
+*.cmake      text svneol=native#text/plain
+*.css        text svneol=native#text/css
+*.dtd        text svneol=native#text/xml
+*.htm        text svneol=native#text/html
+*.html       text svneol=native#text/html
+*.ini        text svneol=native#text/plain
+*.log        text svneol=native#text/plain
+*.mak        text svneol=native#text/plain
+*.qbk        text svneol=native#text/plain
+*.rst        text svneol=native#text/plain
+*.sql        text svneol=native#text/x-sql
+*.txt        text svneol=native#text/plain
+*.xhtml      text svneol=native#text/xhtml%2Bxml
+*.xml        text svneol=native#text/xml
+*.xsd        text svneol=native#text/xml
+*.xsl        text svneol=native#text/xml
+*.xslt       text svneol=native#text/xml
+*.xul        text svneol=native#text/xul
+*.yml        text svneol=native#text/plain
+boost-no-inspect text svneol=native#text/plain
+CHANGES      text svneol=native#text/plain
+COPYING      text svneol=native#text/plain
+INSTALL      text svneol=native#text/plain
+Jamfile      text svneol=native#text/plain
+Jamroot      text svneol=native#text/plain
+Jamfile.v2   text svneol=native#text/plain
+Jamrules     text svneol=native#text/plain
+Makefile*    text svneol=native#text/plain
+README       text svneol=native#text/plain
+TODO         text svneol=native#text/plain
+
+# Code formats
+*.c          text svneol=native#text/plain
+*.cpp        text svneol=native#text/plain
+*.h          text svneol=native#text/plain
+*.hpp        text svneol=native#text/plain
+*.ipp        text svneol=native#text/plain
+*.tpp        text svneol=native#text/plain
+*.jam        text svneol=native#text/plain
+*.java       text svneol=native#text/plain
diff --git a/Changelog b/Changelog
new file mode 100644
index 0000000..0d71a94
--- /dev/null
+++ b/Changelog
@@ -0,0 +1,25 @@
+Version 1.1.0
+-------------
+
+2014-09-16: Nasos Iliopoulos <>
+	* feature: Merged matrix row and column facades ( matrix as a vector of rows/columns )
+	
+2014-05-03: David Bellot <david.bellot@gmail.com>
+	* removed doxygen documentation from main source
+	* changed the changelog file for GNU format
+	* changed doc extension to a more "standard" .html
+
+2014-04-08 Nasos Iliopoulos <>
+
+	* bugfix: introduced an additional swap implementation for index_pair_array and
+		index_triple_array to allow proper compilation of sparse containers
+		with g++>4.8 (4.7 also?) in C++11 mode.
+
+2014-04-02 Nasos Iliopoulos <>
+
+	* Added changelog
+	* bugfix: corrected a big number of warnings coming from stray typedefs. Other
+		similar issues may be present that are not triggered by the unit tests
+	* bugfix: Corrected the banded matrix bug (https://svn.boost.org/trac/boost/ticket/7549) 
+		and updated appropriate unit tests. To enable the old (incorrect though) 
+		behaviour one should define BOOST_UBLAS_LEGACY_BANDED.
diff --git a/IDEs/qtcreator/benchmarks/bench1/bench1.pro b/IDEs/qtcreator/benchmarks/bench1/bench1.pro
new file mode 100644
index 0000000..685802b
--- /dev/null
+++ b/IDEs/qtcreator/benchmarks/bench1/bench1.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = bench1
+
+!include (../configuration.pri)
+
+OTHER_FILES += \
+    ../../../../benchmarks/bench1/Jamfile.v2
+
+HEADERS += \
+    ../../../../benchmarks/bench1/bench1.hpp
+
+SOURCES += \
+    ../../../../benchmarks/bench1/bench13.cpp \
+    ../../../../benchmarks/bench1/bench12.cpp \
+    ../../../../benchmarks/bench1/bench11.cpp \
+    ../../../../benchmarks/bench1/bench1.cpp
diff --git a/IDEs/qtcreator/benchmarks/bench2/bench2.pro b/IDEs/qtcreator/benchmarks/bench2/bench2.pro
new file mode 100644
index 0000000..b667a3f
--- /dev/null
+++ b/IDEs/qtcreator/benchmarks/bench2/bench2.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = bench2
+
+!include (../configuration.pri)
+
+OTHER_FILES += \
+    ../../../../benchmarks/bench2/Jamfile.v2
+
+HEADERS += \
+    ../../../../benchmarks/bench2/bench2.hpp
+
+SOURCES += \
+    ../../../../benchmarks/bench2/bench23.cpp \
+    ../../../../benchmarks/bench2/bench22.cpp \
+    ../../../../benchmarks/bench2/bench21.cpp \
+    ../../../../benchmarks/bench2/bench2.cpp
diff --git a/IDEs/qtcreator/benchmarks/bench3/bench3.pro b/IDEs/qtcreator/benchmarks/bench3/bench3.pro
new file mode 100644
index 0000000..21f561f
--- /dev/null
+++ b/IDEs/qtcreator/benchmarks/bench3/bench3.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = bench3
+
+!include (../configuration.pri)
+
+OTHER_FILES += \
+    ../../../../benchmarks/bench3/Jamfile.v2
+
+HEADERS += \
+    ../../../../benchmarks/bench3/bench3.hpp
+
+SOURCES += \
+    ../../../../benchmarks/bench3/bench33.cpp \
+    ../../../../benchmarks/bench3/bench32.cpp \
+    ../../../../benchmarks/bench3/bench31.cpp \
+    ../../../../benchmarks/bench3/bench3.cpp
diff --git a/IDEs/qtcreator/benchmarks/bench4/bench4.pro b/IDEs/qtcreator/benchmarks/bench4/bench4.pro
new file mode 100644
index 0000000..354bb47
--- /dev/null
+++ b/IDEs/qtcreator/benchmarks/bench4/bench4.pro
@@ -0,0 +1,15 @@
+TEMPLATE = app
+TARGET = bench4
+
+!include (../configuration.pri)
+
+DEFINES += BOOST_UBLAS_USE_INTERVAL
+
+OTHER_FILES += \
+    ../../../../benchmarks/bench4/Jamfile.v2
+
+SOURCES += \
+    ../../../../benchmarks/bench4/bench43.cpp \
+    ../../../../benchmarks/bench4/bench42.cpp \
+    ../../../../benchmarks/bench4/bench41.cpp \
+    ../../../../benchmarks/bench4/bench4.cpp
diff --git a/IDEs/qtcreator/benchmarks/bench5/bench5.pro b/IDEs/qtcreator/benchmarks/bench5/bench5.pro
new file mode 100644
index 0000000..e450911
--- /dev/null
+++ b/IDEs/qtcreator/benchmarks/bench5/bench5.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+TARGET = bench5
+
+!include (../configuration.pri)
+
+DEFINES += BOOST_UBLAS_USE_INTERVAL
+
+OTHER_FILES += \
+    ../../../../benchmarks/bench5/Jamfile.v2
+
+SOURCES += \
+    ../../../../benchmarks/bench5/assignment_bench.cpp
diff --git a/IDEs/qtcreator/benchmarks/benchmarks.pro b/IDEs/qtcreator/benchmarks/benchmarks.pro
new file mode 100644
index 0000000..4acf2d6
--- /dev/null
+++ b/IDEs/qtcreator/benchmarks/benchmarks.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = bench1 bench2 bench3 bench4 bench5
diff --git a/IDEs/qtcreator/benchmarks/configuration.pri b/IDEs/qtcreator/benchmarks/configuration.pri
new file mode 100644
index 0000000..07ffcae
--- /dev/null
+++ b/IDEs/qtcreator/benchmarks/configuration.pri
@@ -0,0 +1,13 @@
+CONFIG -= qt
+CONFIG += depend_includepath
+
+# ublas include directory
+INCLUDEPATH += \
+    ../../../../include
+
+# If ublas tests are build with boost source code then,
+# then boost headers and boost libraries should be used.
+exists(../../../../../../../boost-build.jam) {
+    INCLUDEPATH += ../../../../../../..
+    #LIBS += -L../../../../../../../stage/lib
+}
diff --git a/IDEs/qtcreator/include/detail/detail.pri b/IDEs/qtcreator/include/detail/detail.pri
new file mode 100644
index 0000000..711972d
--- /dev/null
+++ b/IDEs/qtcreator/include/detail/detail.pri
@@ -0,0 +1,12 @@
+HEADERS += \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/vector_assign.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/temporary.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/returntype_deduction.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/raw.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/matrix_assign.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/iterator.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/duff.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/documentation.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/definitions.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/config.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/detail/concepts.hpp
diff --git a/IDEs/qtcreator/include/experimental/experimental.pri b/IDEs/qtcreator/include/experimental/experimental.pri
new file mode 100644
index 0000000..41dc6c4
--- /dev/null
+++ b/IDEs/qtcreator/include/experimental/experimental.pri
@@ -0,0 +1,2 @@
+HEADERS += \
+    $${INCLUDE_DIR}/boost/numeric/ublas/experimental/sparse_view.hpp
diff --git a/IDEs/qtcreator/include/include.pro b/IDEs/qtcreator/include/include.pro
new file mode 100644
index 0000000..5815a01
--- /dev/null
+++ b/IDEs/qtcreator/include/include.pro
@@ -0,0 +1,47 @@
+TEMPLATE = lib
+TARGET = ublas
+
+CONFIG += \
+    staticlib \
+    depend_includepath
+CONFIG -= qt
+
+INCLUDE_DIR = ../../../include
+
+include(detail/detail.pri)
+include(experimental/experimental.pri)
+include(operation/operation.pri)
+include(traits/traits.pri)
+
+HEADERS += \
+    $${INCLUDE_DIR}/boost/numeric/ublas/vector_sparse.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/vector_proxy.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/vector_of_vector.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/vector_expression.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/vector.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/triangular.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/traits.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/tags.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/symmetric.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/storage_sparse.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/storage.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/operation_sparse.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/operations.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/operation_blocked.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/operation.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/matrix_sparse.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/matrix_proxy.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/matrix_expression.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/matrix.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/lu.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/io.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/hermitian.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/fwd.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/functional.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/expression_types.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/exception.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/doxydoc.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/blas.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/banded.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/assignment.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/matrix_vector.hpp
diff --git a/IDEs/qtcreator/include/operation/operation.pri b/IDEs/qtcreator/include/operation/operation.pri
new file mode 100644
index 0000000..519c4f4
--- /dev/null
+++ b/IDEs/qtcreator/include/operation/operation.pri
@@ -0,0 +1,7 @@
+HEADERS += \
+    $${INCLUDE_DIR}/boost/numeric/ublas/operation/size.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/operation/num_rows.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/operation/num_columns.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/operation/end.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/operation/c_array.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/operation/begin.hpp
diff --git a/IDEs/qtcreator/include/traits/traits.pri b/IDEs/qtcreator/include/traits/traits.pri
new file mode 100644
index 0000000..de327dc
--- /dev/null
+++ b/IDEs/qtcreator/include/traits/traits.pri
@@ -0,0 +1,4 @@
+HEADERS += \
+    $${INCLUDE_DIR}/boost/numeric/ublas/traits/iterator_type.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/traits/const_iterator_type.hpp \
+    $${INCLUDE_DIR}/boost/numeric/ublas/traits/c_array.hpp
diff --git a/IDEs/qtcreator/test/begin_end.pro b/IDEs/qtcreator/test/begin_end.pro
new file mode 100644
index 0000000..03c4c62
--- /dev/null
+++ b/IDEs/qtcreator/test/begin_end.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = begin_end
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/begin_end.cpp
diff --git a/IDEs/qtcreator/test/comp_mat_erase.pro b/IDEs/qtcreator/test/comp_mat_erase.pro
new file mode 100644
index 0000000..63960ae
--- /dev/null
+++ b/IDEs/qtcreator/test/comp_mat_erase.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = comp_mat_erase
+
+!include (configuration.pri)
+
+SOURCES += \
+    ../../../test/comp_mat_erase.cpp
diff --git a/IDEs/qtcreator/test/concepts.pro b/IDEs/qtcreator/test/concepts.pro
new file mode 100644
index 0000000..c4c0bca
--- /dev/null
+++ b/IDEs/qtcreator/test/concepts.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = concepts
+
+!include (configuration.pri)
+
+DEFINES += \
+    EXTERNAL
+# INTERAL
+# SKIP_BAD
+
+linux: icc: QMAKE_CXXFLAGS += -Xc
+macx: QMAKE_CXXFLAGS += -fabi-version=0
+
+
+SOURCES += \
+    ../../../test/concepts.cpp
diff --git a/IDEs/qtcreator/test/configuration.pri b/IDEs/qtcreator/test/configuration.pri
new file mode 100644
index 0000000..3fdb4aa
--- /dev/null
+++ b/IDEs/qtcreator/test/configuration.pri
@@ -0,0 +1,51 @@
+CONFIG -= qt
+CONFIG += \
+    depend_includepath \
+    debug
+QMAKE_CXXFLAGS += -fno-inline
+
+# Create a directory for each test.
+DESTDIR = $${TARGET}
+OBJECTS_DIR = $${TARGET}
+
+UBLAS_TESTSET = \
+    USE_DOUBLE USE_STD_COMPLEX \
+    USE_RANGE USE_SLICE \
+    USE_UNBOUNDED_ARRAY USE_STD_VECTOR USE_BOUNDED_VECTOR USE_MATRIX
+
+UBLAS_TESTSET_SPARSE = \
+    USE_DOUBLE USE_STD_COMPLEX \
+    USE_UNBOUNDED_ARRAY \
+    USE_MAP_ARRAY USE_STD_MAP \
+    USE_MAPPED_VECTOR USE_COMPRESSED_VECTOR \
+    USE_MAPPED_MATRIX USE_COMPRESSED_MATRIX
+    # USE_RANGE USE_SLICE        # Too complex for regression testing
+
+UBLAS_TESTSET_SPARSE_COO = \
+    USE_DOUBLE USE_STD_COMPLEX \
+    USE_UNBOUNDED_ARRAY \
+    USE_COORDINATE_VECTOR \
+    USE_COORDINATE_MATRIX
+
+DEFINES += BOOST_UBLAS_NO_EXCEPTIONS
+
+#Visual age IBM
+xlc: DEFINES += BOOST_UBLAS_NO_ELEMENT_PROXIES
+
+# ublas include and test directory are included
+INCLUDEPATH += \
+    ../../../include \
+    ../../test
+
+# If ublas tests are build with boost source code then,
+# then boost headers and boost libraries should be used.
+exists(../../../../../../boost-build.jam) {
+    INCLUDEPATH += ../../../../../..
+    LIBS += -L../../../../../../stage/lib
+    QMAKE_RPATHDIR += ../../../../../../stage/lib
+}
+
+# Execute test once compiled.
+win32: QMAKE_POST_LINK = ./$${DESTDIR}/$${TARGET}.exe
+else: QMAKE_POST_LINK = ./$${DESTDIR}/$${TARGET}
+
diff --git a/IDEs/qtcreator/test/num_columns.pro b/IDEs/qtcreator/test/num_columns.pro
new file mode 100644
index 0000000..8a28199
--- /dev/null
+++ b/IDEs/qtcreator/test/num_columns.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = num_columns
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/num_columns.cpp
diff --git a/IDEs/qtcreator/test/num_rows.pro b/IDEs/qtcreator/test/num_rows.pro
new file mode 100644
index 0000000..dc0a229
--- /dev/null
+++ b/IDEs/qtcreator/test/num_rows.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = num_rows
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/num_rows.cpp
diff --git a/IDEs/qtcreator/test/placement_new.pro b/IDEs/qtcreator/test/placement_new.pro
new file mode 100644
index 0000000..d19a747
--- /dev/null
+++ b/IDEs/qtcreator/test/placement_new.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = placement_new
+
+!include (configuration.pri)
+
+SOURCES += \
+    ../../../test/placement_new.cpp
diff --git a/IDEs/qtcreator/test/size.pro b/IDEs/qtcreator/test/size.pro
new file mode 100644
index 0000000..59a0403
--- /dev/null
+++ b/IDEs/qtcreator/test/size.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = size
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/size.cpp
diff --git a/IDEs/qtcreator/test/sparse_view_test.pro b/IDEs/qtcreator/test/sparse_view_test.pro
new file mode 100644
index 0000000..02b3eb0
--- /dev/null
+++ b/IDEs/qtcreator/test/sparse_view_test.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = sparse_view_test
+
+!include (configuration.pri)
+
+SOURCES += \
+    ../../../test/sparse_view_test.cpp
diff --git a/IDEs/qtcreator/test/test1.pro b/IDEs/qtcreator/test/test1.pro
new file mode 100644
index 0000000..d1123c4
--- /dev/null
+++ b/IDEs/qtcreator/test/test1.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = test1
+
+!include (configuration.pri)
+
+DEFINES += $$UBLAS_TESTSET
+
+HEADERS += ../../../test/test1.hpp
+
+SOURCES += \
+    ../../../test/test13.cpp \
+    ../../../test/test12.cpp \
+    ../../../test/test11.cpp \
+    ../../../test/test1.cpp
diff --git a/IDEs/qtcreator/test/test2.pro b/IDEs/qtcreator/test/test2.pro
new file mode 100644
index 0000000..00fb53f
--- /dev/null
+++ b/IDEs/qtcreator/test/test2.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = test2
+
+!include (configuration.pri)
+
+DEFINES += $$UBLAS_TESTSET
+
+HEADERS += ../../../test/test2.hpp
+
+SOURCES += \
+    ../../../test/test23.cpp \
+    ../../../test/test22.cpp \
+    ../../../test/test21.cpp \
+    ../../../test/test2.cpp
diff --git a/IDEs/qtcreator/test/test3.pro b/IDEs/qtcreator/test/test3.pro
new file mode 100644
index 0000000..f4fd021
--- /dev/null
+++ b/IDEs/qtcreator/test/test3.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = test3
+
+!include (configuration.pri)
+
+DEFINES += $$UBLAS_TESTSET_SPARSE
+
+HEADERS += ../../../test/test3.hpp
+
+SOURCES += \
+    ../../../test/test33.cpp \
+    ../../../test/test32.cpp \
+    ../../../test/test31.cpp \
+    ../../../test/test3.cpp
diff --git a/IDEs/qtcreator/test/test3_coo.pro b/IDEs/qtcreator/test/test3_coo.pro
new file mode 100644
index 0000000..27e3ca3
--- /dev/null
+++ b/IDEs/qtcreator/test/test3_coo.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = test3_coo
+
+!include (configuration.pri)
+
+DEFINES += $$UBLAS_TESTSET_SPARSE_COO
+
+HEADERS += ../../../test/test3.hpp
+
+SOURCES += \
+    ../../../test/test33.cpp \
+    ../../../test/test32.cpp \
+    ../../../test/test31.cpp \
+    ../../../test/test3.cpp
diff --git a/IDEs/qtcreator/test/test3_mvov.pro b/IDEs/qtcreator/test/test3_mvov.pro
new file mode 100644
index 0000000..f0a46dc
--- /dev/null
+++ b/IDEs/qtcreator/test/test3_mvov.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+TARGET = test3_mvov
+
+!include (configuration.pri)
+
+DEFINES += \
+    USE_FLOAT \
+    USE_DOUBLE \
+    USE_STD_COMPLEX \
+    USE_STD_MAP \
+    USE_MAPPED_VECTOR_OF_MAPPED_VECTOR
+
+HEADERS += ../../../test/test3.hpp
+
+SOURCES += \
+    ../../../test/test33.cpp \
+    ../../../test/test32.cpp \
+    ../../../test/test31.cpp \
+    ../../../test/test3.cpp
diff --git a/IDEs/qtcreator/test/test4.pro b/IDEs/qtcreator/test/test4.pro
new file mode 100644
index 0000000..19da3f8
--- /dev/null
+++ b/IDEs/qtcreator/test/test4.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = test4
+
+!include (configuration.pri)
+
+DEFINES += $$UBLAS_TESTSET
+
+HEADERS += ../../../test/test4.hpp
+
+SOURCES += \
+    ../../../test/test43.cpp \
+    ../../../test/test42.cpp \
+    ../../../test/test4.cpp
diff --git a/IDEs/qtcreator/test/test5.pro b/IDEs/qtcreator/test/test5.pro
new file mode 100644
index 0000000..3f27384
--- /dev/null
+++ b/IDEs/qtcreator/test/test5.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = test5
+
+!include (configuration.pri)
+
+DEFINES += $$UBLAS_TESTSET
+
+HEADERS += ../../../test/test5.hpp
+
+SOURCES += \
+    ../../../test/test53.cpp \
+    ../../../test/test52.cpp \
+    ../../../test/test5.cpp
diff --git a/IDEs/qtcreator/test/test6.pro b/IDEs/qtcreator/test/test6.pro
new file mode 100644
index 0000000..0664ce4
--- /dev/null
+++ b/IDEs/qtcreator/test/test6.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = test6
+
+!include (configuration.pri)
+
+DEFINES += $$UBLAS_TESTSET
+
+HEADERS += ../../../test/test6.hpp
+
+SOURCES += \
+    ../../../test/test63.cpp \
+    ../../../test/test62.cpp \
+    ../../../test/test6.cpp
diff --git a/IDEs/qtcreator/test/test7.pro b/IDEs/qtcreator/test/test7.pro
new file mode 100644
index 0000000..5410184
--- /dev/null
+++ b/IDEs/qtcreator/test/test7.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = test7
+
+!include (configuration.pri)
+
+DEFINES += \
+    BOOST_UBLAS_USE_INTERVAL \
+    $${UBLAS_TESTSET}
+
+HEADERS += ../../../test/test7.hpp
+
+SOURCES += \
+    ../../../test/test73.cpp \
+    ../../../test/test72.cpp \
+    ../../../test/test71.cpp \
+    ../../../test/test7.cpp
diff --git a/IDEs/qtcreator/test/test_assignment.pro b/IDEs/qtcreator/test/test_assignment.pro
new file mode 100644
index 0000000..1ad6ca3
--- /dev/null
+++ b/IDEs/qtcreator/test/test_assignment.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = test_assignment
+
+!include (configuration.pri)
+
+DEFINES += \
+    BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_assignment.cpp
diff --git a/IDEs/qtcreator/test/test_banded_storage_layout.pro b/IDEs/qtcreator/test/test_banded_storage_layout.pro
new file mode 100644
index 0000000..78a96dc
--- /dev/null
+++ b/IDEs/qtcreator/test/test_banded_storage_layout.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = test_banded_storage_layout
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_banded_storage_layout.cpp
diff --git a/IDEs/qtcreator/test/test_complex_norms.pro b/IDEs/qtcreator/test/test_complex_norms.pro
new file mode 100644
index 0000000..e7c431e
--- /dev/null
+++ b/IDEs/qtcreator/test/test_complex_norms.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = test_complex_norms
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_complex_norms.cpp
diff --git a/IDEs/qtcreator/test/test_coordinate_matrix_always_do_full_sort.pro b/IDEs/qtcreator/test/test_coordinate_matrix_always_do_full_sort.pro
new file mode 100644
index 0000000..0c93dd0
--- /dev/null
+++ b/IDEs/qtcreator/test/test_coordinate_matrix_always_do_full_sort.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = test_coordinate_matrix_always_do_full_sort
+
+!include (configuration.pri)
+
+DEFINES += \
+    BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_coordinate_matrix_sort.cpp
diff --git a/IDEs/qtcreator/test/test_coordinate_matrix_inplace_merge.pro b/IDEs/qtcreator/test/test_coordinate_matrix_inplace_merge.pro
new file mode 100644
index 0000000..0dee5eb
--- /dev/null
+++ b/IDEs/qtcreator/test/test_coordinate_matrix_inplace_merge.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = test_coordinate_matrix_inplace_merge
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_coordinate_matrix_inplace_merge.cpp
diff --git a/IDEs/qtcreator/test/test_coordinate_matrix_sort.pro b/IDEs/qtcreator/test/test_coordinate_matrix_sort.pro
new file mode 100644
index 0000000..ea94561
--- /dev/null
+++ b/IDEs/qtcreator/test/test_coordinate_matrix_sort.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = test_coordinate_matrix_sort
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_coordinate_matrix_sort.cpp
diff --git a/IDEs/qtcreator/test/test_coordinate_vector_inplace_merge.pro b/IDEs/qtcreator/test/test_coordinate_vector_inplace_merge.pro
new file mode 100644
index 0000000..a86ce2a
--- /dev/null
+++ b/IDEs/qtcreator/test/test_coordinate_vector_inplace_merge.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+TARGET = test_coordinate_vector_inplace_merge
+
+!include (configuration.pri)
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_coordinate_vector_inplace_merge.cpp
diff --git a/IDEs/qtcreator/test/test_fixed_containers.pro b/IDEs/qtcreator/test/test_fixed_containers.pro
new file mode 100644
index 0000000..6012748
--- /dev/null
+++ b/IDEs/qtcreator/test/test_fixed_containers.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = test_fixed_containers
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_fixed_containers.cpp
diff --git a/IDEs/qtcreator/test/test_inplace_solve_basic.pro b/IDEs/qtcreator/test/test_inplace_solve_basic.pro
new file mode 100644
index 0000000..42bc3db
--- /dev/null
+++ b/IDEs/qtcreator/test/test_inplace_solve_basic.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = test_inplace_solve_basic
+
+!include (configuration.pri)
+
+DEFINES += \
+    $$UBLAS_TESTSET
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_inplace_solve.cpp
diff --git a/IDEs/qtcreator/test/test_inplace_solve_mvov.pro b/IDEs/qtcreator/test/test_inplace_solve_mvov.pro
new file mode 100644
index 0000000..a1d1316
--- /dev/null
+++ b/IDEs/qtcreator/test/test_inplace_solve_mvov.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = test_inplace_solve_mvov
+
+!include (configuration.pri)
+
+DEFINES += \
+    USE_MAPPED_VECTOR_OF_MAPPED_VECTOR
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_inplace_solve.cpp
diff --git a/IDEs/qtcreator/test/test_inplace_solve_sparse.pro b/IDEs/qtcreator/test/test_inplace_solve_sparse.pro
new file mode 100644
index 0000000..9f9a32a
--- /dev/null
+++ b/IDEs/qtcreator/test/test_inplace_solve_sparse.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = test_inplace_solve_sparse
+
+!include (configuration.pri)
+
+DEFINES += \
+    $$UBLAS_TESTSET_SPARSE \
+    $$UBLAS_TESTSET_SPARSE_COO
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_inplace_solve.cpp
diff --git a/IDEs/qtcreator/test/test_lu.pro b/IDEs/qtcreator/test/test_lu.pro
new file mode 100644
index 0000000..0f20339
--- /dev/null
+++ b/IDEs/qtcreator/test/test_lu.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = test_lu
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/common/testhelper.hpp
+
+SOURCES += \
+    ../../../test/test_lu.cpp
diff --git a/IDEs/qtcreator/test/test_matrix_vector.pro b/IDEs/qtcreator/test/test_matrix_vector.pro
new file mode 100644
index 0000000..d61b70b
--- /dev/null
+++ b/IDEs/qtcreator/test/test_matrix_vector.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = test_matrix_vector
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_matrix_vector.cpp
+
+INCLUDEPATH += \
+    ../../../include
diff --git a/IDEs/qtcreator/test/test_ticket7296.pro b/IDEs/qtcreator/test/test_ticket7296.pro
new file mode 100644
index 0000000..98752cf
--- /dev/null
+++ b/IDEs/qtcreator/test/test_ticket7296.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+TARGET = test_ticket7296
+
+!include (configuration.pri)
+
+HEADERS += \
+    ../../../test/utils.hpp
+
+SOURCES += \
+    ../../../test/test_ticket7296.cpp
diff --git a/IDEs/qtcreator/test/test_triangular.pro b/IDEs/qtcreator/test/test_triangular.pro
new file mode 100644
index 0000000..15c8ce1
--- /dev/null
+++ b/IDEs/qtcreator/test/test_triangular.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = test_triangular
+
+!include (configuration.pri)
+
+DEFINES += \
+    BOOST_CHRONO_DYN_LINK=1 \
+    BOOST_CHRONO_THREAD_DISABLED \
+    BOOST_SYSTEM_DYN_LINK=1 \
+    BOOST_SYSTEM_NO_DEPRECATED \
+    BOOST_TIMER_DYN_LINK=1
+
+SOURCES += \
+    ../../../test/test_triangular.cpp
+
+LIBS += -lboost_timer -lboost_system -lboost_chrono
diff --git a/IDEs/qtcreator/test/triangular_access.pro b/IDEs/qtcreator/test/triangular_access.pro
new file mode 100644
index 0000000..98a8706
--- /dev/null
+++ b/IDEs/qtcreator/test/triangular_access.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+TARGET = triangular_access
+
+!include (configuration.pri)
+
+DEFINES += NOMESSAGES
+
+HEADERS += \
+    ../../../test/common/testhelper.hpp
+
+SOURCES += \
+    ../../../test/triangular_access.cpp
diff --git a/IDEs/qtcreator/test/triangular_layout.pro b/IDEs/qtcreator/test/triangular_layout.pro
new file mode 100644
index 0000000..dcfd36f
--- /dev/null
+++ b/IDEs/qtcreator/test/triangular_layout.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = triangular_layout
+
+!include (configuration.pri)
+
+SOURCES += \
+    ../../../test/triangular_layout.cpp
diff --git a/IDEs/qtcreator/tests.pri b/IDEs/qtcreator/tests.pri
new file mode 100644
index 0000000..6ece4ac
--- /dev/null
+++ b/IDEs/qtcreator/tests.pri
@@ -0,0 +1,74 @@
+OTHER_FILES += \
+    ../../test/README \
+    ../../test/Jamfile.v2
+
+SUBDIRS += \
+    begin_end \
+    comp_mat_erase \
+    concepts \
+    num_columns \
+    num_rows \
+    placement_new \
+    size \
+    sparse_view_test \
+    test1 \
+    test2 \
+    test3 \
+    test3_coo \
+    test3_mvov \
+    test4 \
+    test5 \
+    test6 \
+    test7 \
+    test_assignment \
+    test_banded_storage_layout \
+    test_complex_norms \
+    test_coordinate_matrix_inplace_merge \
+    test_coordinate_matrix_sort \
+    test_coordinate_matrix_always_do_full_sort \
+    test_coordinate_vector_inplace_merge \
+    test_fixed_containers \
+    test_inplace_solve_basic \
+    test_inplace_solve_sparse \
+    test_inplace_solve_mvov \
+    test_lu \
+    test_matrix_vector \
+    test_ticket7296 \
+    test_triangular \
+    triangular_access \
+    triangular_layout
+
+begin_end.file = test/begin_end.pro
+comp_mat_erase.file = test/comp_mat_erase.pro
+concepts.file = test/concepts.pro
+num_columns.file = test/num_columns.pro
+num_rows.file = test/num_rows.pro
+placement_new.file = test/placement_new.pro
+size.file = test/size.pro
+sparse_view_test.file = test/sparse_view_test.pro
+test1.file = test/test1.pro
+test2.file = test/test2.pro
+test3.file = test/test3.pro
+test3_coo.file = test/test3_coo.pro
+test3_mvov.file = test/test3_mvov.pro
+test4.file = test/test4.pro
+test5.file = test/test5.pro
+test6.file = test/test6.pro
+test7.file = test/test7.pro
+test_assignment.file = test/test_assignment.pro
+test_banded_storage_layout.file = test/test_banded_storage_layout.pro
+test_complex_norms.file = test/test_complex_norms.pro
+test_coordinate_matrix_inplace_merge.file = test/test_coordinate_matrix_inplace_merge.pro
+test_coordinate_matrix_sort.file = test/test_coordinate_matrix_sort.pro
+test_coordinate_matrix_always_do_full_sort.file = test/test_coordinate_matrix_always_do_full_sort.pro
+test_coordinate_vector_inplace_merge.file = test/test_coordinate_vector_inplace_merge.pro
+test_fixed_containers.file = test/test_fixed_containers.pro
+test_inplace_solve_basic.file = test/test_inplace_solve_basic.pro
+test_inplace_solve_sparse.file = test/test_inplace_solve_sparse.pro
+test_inplace_solve_mvov.file = test/test_inplace_solve_mvov.pro
+test_lu.file = test/test_lu.pro
+test_matrix_vector.file = test/test_matrix_vector.pro
+test_ticket7296.file = test/test_ticket7296.pro
+test_triangular.file = test/test_triangular.pro
+triangular_access.file = test/triangular_access.pro
+triangular_layout.file = test/triangular_layout.pro
diff --git a/IDEs/qtcreator/ublas_develop.pro b/IDEs/qtcreator/ublas_develop.pro
new file mode 100644
index 0000000..7364283
--- /dev/null
+++ b/IDEs/qtcreator/ublas_develop.pro
@@ -0,0 +1,6 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+SUBDIRS = include benchmarks
+OTHER_FILES += ../../changelog.txt
+
+include (tests.pri)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a0387df
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+ublas
+=====
+
+The Boost.uBLAS Linear Algebra Library v1.0
+
+- To follow development and test experimental features, you can clone the Github project uBLAS/ublas
+at https://github.com/uBLAS/ublas
+- A development wiki is available at https://github.com/uBLAS/ublas/wiki
+- A mailing-list is available at http://lists.boost.org/ublas/
+- For any other questions, you can contact David at david.bellot@gmail.com
+
+- version numbers have never been used for this library until 02 March 2014.
+  So we start at v1.0 on that day.
+
+last update: 1 April 2014
diff --git a/benchmarks/bench1/Jamfile.v2 b/benchmarks/bench1/Jamfile.v2
new file mode 100644
index 0000000..77b11c7
--- /dev/null
+++ b/benchmarks/bench1/Jamfile.v2
@@ -0,0 +1,10 @@
+# Copyright (c) 2004 Michael Stevens
+# Use, modification and distribution are subject to the
+# Boost Software License, Version 1.0. (See accompanying file
+# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# bench1 - measure the abstraction penalty of dense matrix and vector operations.
+
+exe bench1
+    : bench1.cpp bench11.cpp bench12.cpp bench13.cpp
+    ;
diff --git a/benchmarks/bench1/bench1.cpp b/benchmarks/bench1/bench1.cpp
new file mode 100644
index 0000000..87478e1
--- /dev/null
+++ b/benchmarks/bench1/bench1.cpp
@@ -0,0 +1,122 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench1.hpp"
+
+void header (std::string text) {
+    std::cout << text << std::endl;
+}
+
+template<class T>
+struct peak_c_plus {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static T s (0);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                s += T (0);
+//                sink_scalar (s);
+            }
+            footer<value_type> () (0, 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class T>
+struct peak_c_multiplies {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static T s (1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                s *= T (1);
+//                sink_scalar (s);
+            }
+            footer<value_type> () (0, 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T>
+void peak<T>::operator () (int runs) {
+    header ("peak");
+
+    header ("plus");
+    peak_c_plus<T> () (runs);
+
+    header ("multiplies");
+    peak_c_multiplies<T> () (runs);
+}
+
+
+template <typename scalar> 
+void do_bench (std::string type_string, int scale)
+{
+    header (type_string);
+    peak<scalar> () (1000000 * scale);
+
+    header (type_string + ", 3");
+    bench_1<scalar, 3> () (1000000 * scale);
+    bench_2<scalar, 3> () (300000 * scale);
+    bench_3<scalar, 3> () (100000 * scale);
+
+    header (type_string + ", 10");
+    bench_1<scalar, 10> () (300000 * scale);
+    bench_2<scalar, 10> () (30000 * scale);
+    bench_3<scalar, 10> () (3000 * scale);
+
+    header (type_string + ", 30");
+    bench_1<scalar, 30> () (100000 * scale);
+    bench_2<scalar, 30> () (3000 * scale);
+    bench_3<scalar, 30> () (100 * scale);
+
+    header (type_string + ", 100");
+    bench_1<scalar, 100> () (30000 * scale);
+    bench_2<scalar, 100> () (300 * scale);
+    bench_3<scalar, 100> () (3 * scale);
+}
+
+int main (int argc, char *argv []) {
+
+    int scale = 1;
+    if (argc > 1)
+        scale = std::atoi (argv [1]);
+
+#ifdef USE_FLOAT
+    do_bench<float> ("FLOAT", scale);
+#endif
+
+#ifdef USE_DOUBLE
+    do_bench<double> ("DOUBLE", scale);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    do_bench<std::complex<float> > ("COMPLEX<FLOAT>", scale);
+#endif
+
+#ifdef USE_DOUBLE
+    do_bench<std::complex<double> > ("COMPLEX<DOUBLE>", scale);
+#endif
+#endif
+
+    return 0;
+}
diff --git a/benchmarks/bench1/bench1.hpp b/benchmarks/bench1/bench1.hpp
new file mode 100644
index 0000000..d799463
--- /dev/null
+++ b/benchmarks/bench1/bench1.hpp
@@ -0,0 +1,159 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef BENCH1_H
+#define BENCH1_H
+
+#include <iostream>
+#include <string>
+#include <valarray>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+
+#include <boost/timer.hpp>
+
+
+#define BOOST_UBLAS_NOT_USED(x) (void)(x)
+
+
+namespace ublas = boost::numeric::ublas;
+
+void header (std::string text);
+
+template<class T>
+struct footer {
+    void operator () (int multiplies, int plus, int runs, double elapsed) {
+        std::cout << "elapsed: " << elapsed << " s, "
+                  << (multiplies * ublas::type_traits<T>::multiplies_complexity +
+                      plus * ublas::type_traits<T>::plus_complexity) * runs /
+                     (1024 * 1024 * elapsed) << " Mflops" << std::endl;
+    }
+};
+
+template<class T, int N>
+struct c_vector_traits {
+    typedef T type [N];
+};
+template<class T, int N, int M>
+struct c_matrix_traits {
+    typedef T type [N] [M];
+};
+
+template<class T, int N>
+struct initialize_c_vector  {
+    void operator () (typename c_vector_traits<T, N>::type &v) {
+        for (int i = 0; i < N; ++ i)
+            v [i] = std::rand () * 1.f;
+//            v [i] = 0.f;
+        }
+};
+template<class V>
+BOOST_UBLAS_INLINE
+void initialize_vector (V &v) {
+    int size = v.size ();
+    for (int i = 0; i < size; ++ i)
+        v [i] = std::rand () * 1.f;
+//      v [i] = 0.f;
+}
+
+template<class T, int N, int M>
+struct initialize_c_matrix  {
+    void operator () (typename c_matrix_traits<T, N, M>::type &m) {
+        for (int i = 0; i < N; ++ i)
+            for (int j = 0; j < M; ++ j)
+                m [i] [j] = std::rand () * 1.f;
+//                m [i] [j] = 0.f;
+    }
+};
+template<class M>
+BOOST_UBLAS_INLINE
+void initialize_matrix (M &m) {
+    int size1 = m.size1 ();
+    int size2 = m.size2 ();
+    for (int i = 0; i < size1; ++ i)
+        for (int j = 0; j < size2; ++ j)
+            m (i, j) = std::rand () * 1.f;
+//          m (i, j) = 0.f;
+}
+
+template<class T>
+BOOST_UBLAS_INLINE
+void sink_scalar (const T &s) {
+    static T g_s = s;
+}
+
+template<class T, int N>
+struct sink_c_vector {
+    void operator () (const typename c_vector_traits<T, N>::type &v) {
+        static typename c_vector_traits<T, N>::type g_v;
+        for (int i = 0; i < N; ++ i)
+            g_v [i] = v [i];
+    }
+};
+template<class V>
+BOOST_UBLAS_INLINE
+void sink_vector (const V &v) {
+    static V g_v (v);
+}
+
+template<class T, int N, int M>
+struct sink_c_matrix {
+    void operator () (const typename c_matrix_traits<T, N, M>::type &m) {
+    static typename c_matrix_traits<T, N, M>::type g_m;
+    for (int i = 0; i < N; ++ i)
+        for (int j = 0; j < M; ++ j)
+            g_m [i] [j] = m [i] [j];
+    }
+};
+template<class M>
+BOOST_UBLAS_INLINE
+void sink_matrix (const M &m) {
+    static M g_m (m);
+}
+
+template<class T>
+struct peak {
+    void operator () (int runs);
+};
+
+template<class T, int N>
+struct bench_1 {
+    void operator () (int runs);
+};
+
+template<class T, int N>
+struct bench_2 {
+    void operator () (int runs);
+};
+
+template<class T, int N>
+struct bench_3 {
+    void operator () (int runs);
+};
+
+struct safe_tag {};
+struct fast_tag {};
+
+//#define USE_FLOAT
+#define USE_DOUBLE
+// #define USE_STD_COMPLEX
+
+#define USE_C_ARRAY
+// #define USE_BOUNDED_ARRAY
+#define USE_UNBOUNDED_ARRAY
+// #define USE_STD_VALARRAY
+//#define USE_STD_VECTOR
+
+#endif
+
+
diff --git a/benchmarks/bench1/bench11.cpp b/benchmarks/bench1/bench11.cpp
new file mode 100644
index 0000000..806a422
--- /dev/null
+++ b/benchmarks/bench1/bench11.cpp
@@ -0,0 +1,287 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench1.hpp"
+
+template<class T, int N>
+struct bench_c_inner_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_vector_traits<T, N>::type v1, v2;
+            initialize_c_vector<T, N> () (v1);
+            initialize_c_vector<T, N> () (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                static value_type s (0);
+                for (int j = 0; j < N; ++ j) {
+                    s += v1 [j] * v2 [j];
+                }
+//                sink_scalar (s);
+            }
+            footer<value_type> () (N, N - 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_my_inner_prod {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static V v1 (N), v2 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                static value_type s (0);
+                s = ublas::inner_prod (v1, v2);
+//                sink_scalar (s);
+                BOOST_UBLAS_NOT_USED(s);
+            }
+            footer<value_type> () (N, N - 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_cpp_inner_prod {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static V v1 (N), v2 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                static value_type s (0);
+                s = (v1 * v2).sum ();
+//                sink_scalar (s);
+            }
+            footer<value_type> () (N, N - 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T, int N>
+struct bench_c_vector_add {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_vector_traits<T, N>::type v1, v2, v3;
+            initialize_c_vector<T, N> () (v1);
+            initialize_c_vector<T, N> () (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    v3 [j] = - (v1 [j] + v2 [j]);
+                }
+//                sink_c_vector<T, N> () (v3);
+                BOOST_UBLAS_NOT_USED(v3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_my_vector_add {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static V v1 (N), v2 (N), v3 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v3 = - (v1 + v2);
+//                sink_vector (v3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static V v1 (N), v2 (N), v3 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v3.assign (- (v1 + v2));
+//                sink_vector (v3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_cpp_vector_add {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static V v1 (N), v2 (N), v3 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v3 = - (v1 + v2);
+//                sink_vector (v3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+// Benchmark O (n)
+template<class T, int N>
+void bench_1<T, N>::operator () (int runs) {
+    header ("bench_1");
+
+    header ("inner_prod");
+
+    header ("C array");
+    bench_c_inner_prod<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_vector");
+    bench_my_inner_prod<ublas::c_vector<T, N>, N> () (runs);
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("vector<bounded_array>");
+    bench_my_inner_prod<ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs);
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("vector<unbounded_array>");
+    bench_my_inner_prod<ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs);
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("vector<std::valarray>");
+    bench_my_inner_prod<ublas::vector<T, std::valarray<T> >, N> () ();
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("vector<std::vector>");
+    bench_my_inner_prod<ublas::vector<T, std::vector<T> >, N> () (runs);
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_inner_prod<std::valarray<T>, N> () (runs);
+#endif
+
+    header ("vector + vector");
+
+    header ("C array");
+    bench_c_vector_add<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_vector safe");
+    bench_my_vector_add<ublas::c_vector<T, N>, N> () (runs, safe_tag ());
+
+    header ("c_vector fast");
+    bench_my_vector_add<ublas::c_vector<T, N>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("vector<bounded_array> safe");
+    bench_my_vector_add<ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, safe_tag ());
+
+    header ("vector<bounded_array> fast");
+    bench_my_vector_add<ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("vector<unbounded_array> safe");
+    bench_my_vector_add<ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, safe_tag ());
+
+    header ("vector<unbounded_array> fast");
+    bench_my_vector_add<ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("vector<std::valarray> safe");
+    bench_my_vector_add<ublas::vector<T, std::valarray<T> >, N> () (runs, safe_tag ());
+
+    header ("vector<std::valarray> fast");
+    bench_my_vector_add<ublas::vector<T, std::valarray<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("vector<std::vector> safe");
+    bench_my_vector_add<ublas::vector<T, std::vector<T> >, N> () (runs, safe_tag ());
+
+    header ("vector<std::vector> fast");
+    bench_my_vector_add<ublas::vector<T, std::vector<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_vector_add<std::valarray<T>, N> () (runs);
+#endif
+}
+
+#ifdef USE_FLOAT
+template struct bench_1<float, 3>;
+template struct bench_1<float, 10>;
+template struct bench_1<float, 30>;
+template struct bench_1<float, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_1<double, 3>;
+template struct bench_1<double, 10>;
+template struct bench_1<double, 30>;
+template struct bench_1<double, 100>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_1<std::complex<float>, 3>;
+template struct bench_1<std::complex<float>, 10>;
+template struct bench_1<std::complex<float>, 30>;
+template struct bench_1<std::complex<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_1<std::complex<double>, 3>;
+template struct bench_1<std::complex<double>, 10>;
+template struct bench_1<std::complex<double>, 30>;
+template struct bench_1<std::complex<double>, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench1/bench12.cpp b/benchmarks/bench1/bench12.cpp
new file mode 100644
index 0000000..439188f
--- /dev/null
+++ b/benchmarks/bench1/bench12.cpp
@@ -0,0 +1,491 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench1.hpp"
+
+template<class T, int N>
+struct bench_c_outer_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m;
+            static typename c_vector_traits<T, N>::type v1, v2;
+            initialize_c_vector<T, N> () (v1);
+            initialize_c_vector<T, N> () (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m [j] [k] = - v1 [j] * v2 [k];
+                    }
+                }
+//                sink_c_matrix<T, N, N> () (m);
+            }
+            BOOST_UBLAS_NOT_USED(m);
+
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_my_outer_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m (N, N);
+            static V v1 (N), v2 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m = - ublas::outer_prod (v1, v2);
+//                sink_matrix (m);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m (N, N);
+            static V v1 (N), v2 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m.assign (- ublas::outer_prod (v1, v2));
+//                sink_matrix (m);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_cpp_outer_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m (N * N);
+            static V v1 (N), v2 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m [N * j + k] = - v1 [j] * v2 [k];
+                    }
+                }
+//                sink_vector (m);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T, int N>
+struct bench_c_matrix_vector_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m;
+            static typename c_vector_traits<T, N>::type v1, v2;
+            initialize_c_matrix<T, N, N> () (m);
+            initialize_c_vector<T, N> () (v1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    v2 [j] = 0;
+                    for (int k = 0; k < N; ++ k) {
+                        v2 [j] += m [j] [k] * v1 [k];
+                    }
+                }
+//                sink_c_vector<T, N> () (v2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_my_matrix_vector_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m (N, N);
+            static V v1 (N), v2 (N);
+            initialize_matrix (m);
+            initialize_vector (v1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v2 = ublas::prod (m, v1);
+//                sink_vector (v2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m (N, N);
+            static V v1 (N), v2 (N);
+            initialize_matrix (m);
+            initialize_vector (v1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v2.assign (ublas::prod (m, v1));
+//                sink_vector (v2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_cpp_matrix_vector_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m (N * N);
+            static V v1 (N), v2 (N);
+            initialize_vector (m);
+            initialize_vector (v1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    std::valarray<value_type> row (m [std::slice (N * j, N, 1)]);
+                    v2 [j] = (row * v1).sum ();
+                }
+//                sink_vector (v2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T, int N>
+struct bench_c_matrix_add {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m1, m2, m3;
+            initialize_c_matrix<T, N, N> () (m1);
+            initialize_c_matrix<T, N, N> () (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m3 [j] [k] = - (m1 [j] [k] + m2 [j] [k]);
+                    }
+                }
+//                sink_c_matrix<T, N, N> () (m3);
+            }
+            BOOST_UBLAS_NOT_USED(m3);
+
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_my_matrix_add {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m1 (N, N), m2 (N, N), m3 (N, N);
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3 = - (m1 + m2);
+//                sink_matrix (m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m1 (N, N), m2 (N, N), m3 (N, N);
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3.assign (- (m1 + m2));
+//                sink_matrix (m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_cpp_matrix_add {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m1 (N * N), m2 (N * N), m3 (N * N);
+            initialize_vector (m1);
+            initialize_vector (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3 = - (m1 + m2);
+//                sink_vector (m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+// Benchmark O (n ^ 2)
+template<class T, int N>
+void bench_2<T, N>::operator () (int runs) {
+    header ("bench_2");
+
+    header ("outer_prod");
+
+    header ("C array");
+    bench_c_outer_prod<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_matrix, c_vector safe");
+    bench_my_outer_prod<ublas::c_matrix<T, N, N>,
+                        ublas::c_vector<T, N>, N> () (runs, safe_tag ());
+
+    header ("c_matrix, c_vector fast");
+    bench_my_outer_prod<ublas::c_matrix<T, N, N>,
+                        ublas::c_vector<T, N>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("matrix<bounded_array>, vector<bounded_array> safe");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >,
+                        ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, safe_tag ());
+
+    header ("matrix<bounded_array>, vector<bounded_array> fast");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >,
+                        ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("matrix<unbounded_array>, vector<unbounded_array> safe");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >,
+                        ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<unbounded_array>, vector<unbounded_array> fast");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >,
+                        ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("matrix<std::valarray>, vector<std::valarray> safe");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >,
+                        ublas::vector<T, std::valarray<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::valarray>, vector<std::valarray> fast");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >,
+                        ublas::vector<T, std::valarray<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("matrix<std::vector>, vector<std::vector> safe");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >,
+                        ublas::vector<T, std::vector<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::vector>, vector<std::vector> fast");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >,
+                        ublas::vector<T, std::vector<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_outer_prod<std::valarray<T>, std::valarray<T>, N> () (runs);
+#endif
+
+    header ("prod (matrix, vector)");
+
+    header ("C array");
+    bench_c_matrix_vector_prod<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_matrix, c_vector safe");
+    bench_my_matrix_vector_prod<ublas::c_matrix<T, N, N>,
+                                ublas::c_vector<T, N>, N> () (runs, safe_tag ());
+
+    header ("c_matrix, c_vector fast");
+    bench_my_matrix_vector_prod<ublas::c_matrix<T, N, N>,
+                                ublas::c_vector<T, N>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("matrix<bounded_array>, vector<bounded_array> safe");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >,
+                                ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, safe_tag ());
+
+    header ("matrix<bounded_array>, vector<bounded_array> fast");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >,
+                                ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("matrix<unbounded_array>, vector<unbounded_array> safe");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >,
+                                ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<unbounded_array>, vector<unbounded_array> fast");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >,
+                                ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("matrix<std::valarray>, vector<std::valarray> safe");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >,
+                                ublas::vector<T, std::valarray<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::valarray>, vector<std::valarray> fast");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >,
+                                ublas::vector<T, std::valarray<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("matrix<std::vector>, vector<std::vector> safe");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >,
+                                ublas::vector<T, std::vector<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::vector>, vector<std::vector> fast");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >,
+                                ublas::vector<T, std::vector<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_matrix_vector_prod<std::valarray<T>, std::valarray<T>, N> () (runs);
+#endif
+
+    header ("matrix + matrix");
+
+    header ("C array");
+    bench_c_matrix_add<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_matrix safe");
+    bench_my_matrix_add<ublas::c_matrix<T, N, N>, N> () (runs, safe_tag ());
+
+    header ("c_matrix fast");
+    bench_my_matrix_add<ublas::c_matrix<T, N, N>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("matrix<bounded_array> safe");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, N> () (runs, safe_tag ());
+
+    header ("matrix<bounded_array> fast");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("matrix<unbounded_array> safe");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<unbounded_array> fast");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("matrix<std::valarray> safe");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::valarray<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::valarray> fast");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::valarray<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("matrix<std::vector> safe");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::vector<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::vector> fast");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::vector<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_matrix_add<std::valarray<T>, N> () (runs);
+#endif
+}
+
+#ifdef USE_FLOAT
+template struct bench_2<float, 3>;
+template struct bench_2<float, 10>;
+template struct bench_2<float, 30>;
+template struct bench_2<float, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_2<double, 3>;
+template struct bench_2<double, 10>;
+template struct bench_2<double, 30>;
+template struct bench_2<double, 100>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_2<std::complex<float>, 3>;
+template struct bench_2<std::complex<float>, 10>;
+template struct bench_2<std::complex<float>, 30>;
+template struct bench_2<std::complex<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_2<std::complex<double>, 3>;
+template struct bench_2<std::complex<double>, 10>;
+template struct bench_2<std::complex<double>, 30>;
+template struct bench_2<std::complex<double>, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench1/bench13.cpp b/benchmarks/bench1/bench13.cpp
new file mode 100644
index 0000000..fadb0b6
--- /dev/null
+++ b/benchmarks/bench1/bench13.cpp
@@ -0,0 +1,192 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench1.hpp"
+
+template<class T, int N>
+struct bench_c_matrix_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m1, m2, m3;
+            initialize_c_matrix<T, N, N> () (m1);
+            initialize_c_matrix<T, N, N> () (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m3 [j] [k] = 0;
+                        for (int l = 0; l < N; ++ l) {
+                            m3 [j] [k] += m1 [j] [l] * m2 [l] [k];
+                        }
+                    }
+                }
+//                sink_c_matrix<T, N, N> () (m3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_my_matrix_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m1 (N, N), m2 (N, N), m3 (N, N);
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3 = ublas::prod (m1, m2);
+//                sink_matrix (m3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m1 (N, N), m2 (N, N), m3 (N, N);
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3.assign (ublas::prod (m1, m2));
+//                sink_matrix (m3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_cpp_matrix_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m1 (N * N), m2 (N * N), m3 (N * N);
+            initialize_vector (m1);
+            initialize_vector (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    std::valarray<value_type> row (m1 [std::slice (N * j, N, 1)]);
+                    for (int k = 0; k < N; ++ k) {
+                        std::valarray<value_type> column (m2 [std::slice (k, N, N)]);
+                        m3 [N * j + k] = (row * column).sum ();
+                    }
+                }
+//                sink_vector (m3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+// Benchmark O (n ^ 3)
+template<class T, int N>
+void bench_3<T, N>::operator () (int runs) {
+    header ("bench_3");
+
+    header ("prod (matrix, matrix)");
+
+    header ("C array");
+    bench_c_matrix_prod<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_matrix safe");
+    bench_my_matrix_prod<ublas::c_matrix<T, N, N>, N> () (runs, safe_tag ());
+
+    header ("c_matrix fast");
+    bench_my_matrix_prod<ublas::c_matrix<T, N, N>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("matrix<bounded_array> safe");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, N> () (runs, safe_tag ());
+
+    header ("matrix<bounded_array> fast");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("matrix<unbounded_array> safe");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<unbounded_array> fast");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("matrix<std::valarray> safe");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::valarray> fast");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("matrix<std::vector> safe");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::vector> fast");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_matrix_prod<std::valarray<T>, N> () (runs);
+#endif
+}
+
+#ifdef USE_FLOAT
+template struct bench_3<float, 3>;
+template struct bench_3<float, 10>;
+template struct bench_3<float, 30>;
+template struct bench_3<float, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_3<double, 3>;
+template struct bench_3<double, 10>;
+template struct bench_3<double, 30>;
+template struct bench_3<double, 100>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_3<std::complex<float>, 3>;
+template struct bench_3<std::complex<float>, 10>;
+template struct bench_3<std::complex<float>, 30>;
+template struct bench_3<std::complex<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_3<std::complex<double>, 3>;
+template struct bench_3<std::complex<double>, 10>;
+template struct bench_3<std::complex<double>, 30>;
+template struct bench_3<std::complex<double>, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench2/Jamfile.v2 b/benchmarks/bench2/Jamfile.v2
new file mode 100644
index 0000000..4eb8015
--- /dev/null
+++ b/benchmarks/bench2/Jamfile.v2
@@ -0,0 +1,10 @@
+# Copyright (c) 2004 Michael Stevens
+# Use, modification and distribution are subject to the
+# Boost Software License, Version 1.0. (See accompanying file
+# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# bench2 - measurs the performance of sparse matrix and vector operations.
+
+exe bench2
+    : bench2.cpp bench21.cpp bench22.cpp bench23.cpp
+    ;
diff --git a/benchmarks/bench2/bench2.cpp b/benchmarks/bench2/bench2.cpp
new file mode 100644
index 0000000..43ba152
--- /dev/null
+++ b/benchmarks/bench2/bench2.cpp
@@ -0,0 +1,122 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench2.hpp"
+
+void header (std::string text) {
+    std::cout << text << std::endl;
+}
+
+template<class T>
+struct peak_c_plus {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static T s (0);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                s += T (0);
+//                sink_scalar (s);
+            }
+            footer<value_type> () (0, 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class T>
+struct peak_c_multiplies {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static T s (1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                s *= T (1);
+//                sink_scalar (s);
+            }
+            footer<value_type> () (0, 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T>
+void peak<T>::operator () (int runs) {
+    header ("peak");
+
+    header ("plus");
+    peak_c_plus<T> () (runs);
+
+    header ("multiplies");
+    peak_c_multiplies<T> () (runs);
+}
+
+
+template <typename scalar> 
+void do_bench (std::string type_string, int scale)
+{
+    header (type_string);
+    peak<scalar> () (1000000 * scale);
+
+    header (type_string + ", 3");
+    bench_1<scalar, 3> () (1000000 * scale);
+    bench_2<scalar, 3> () (300000 * scale);
+    bench_3<scalar, 3> () (100000 * scale);
+
+    header (type_string + ", 10");
+    bench_1<scalar, 10> () (300000 * scale);
+    bench_2<scalar, 10> () (30000 * scale);
+    bench_3<scalar, 10> () (3000 * scale);
+
+    header (type_string + ", 30");
+    bench_1<scalar, 30> () (100000 * scale);
+    bench_2<scalar, 30> () (3000 * scale);
+    bench_3<scalar, 30> () (100 * scale);
+
+    header (type_string + ", 100");
+    bench_1<scalar, 100> () (30000 * scale);
+    bench_2<scalar, 100> () (300 * scale);
+    bench_3<scalar, 100> () (3 * scale);
+}
+
+int main (int argc, char *argv []) {
+
+    int scale = 1;
+    if (argc > 1)
+        scale = std::atoi (argv [1]);
+
+#ifdef USE_FLOAT
+    do_bench<float> ("FLOAT", scale);
+#endif
+
+#ifdef USE_DOUBLE
+    do_bench<double> ("DOUBLE", scale);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    do_bench<std::complex<float> > ("COMPLEX<FLOAT>", scale);
+#endif
+
+#ifdef USE_DOUBLE
+    do_bench<std::complex<double> > ("COMPLEX<DOUBLE>", scale);
+#endif
+#endif
+
+    return 0;
+}
diff --git a/benchmarks/bench2/bench2.hpp b/benchmarks/bench2/bench2.hpp
new file mode 100644
index 0000000..efb20a2
--- /dev/null
+++ b/benchmarks/bench2/bench2.hpp
@@ -0,0 +1,182 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef BENCH2_H
+#define BENCH2_H
+
+#include <iostream>
+#include <string>
+#include <valarray>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+
+#include <boost/timer.hpp>
+
+
+#define BOOST_UBLAS_NOT_USED(x) (void)(x)
+
+
+namespace ublas = boost::numeric::ublas;
+
+void header (std::string text);
+
+template<class T>
+struct footer {
+    void operator () (int multiplies, int plus, int runs, double elapsed) {
+        std::cout << "elapsed: " << elapsed << " s, "
+                  << (multiplies * ublas::type_traits<T>::multiplies_complexity +
+                      plus * ublas::type_traits<T>::plus_complexity) * runs /
+                     (1024 * 1024 * elapsed) << " Mflops" << std::endl;
+    }
+};
+
+template<class T, int N>
+struct c_vector_traits {
+    typedef T type [N];
+};
+template<class T, int N, int M>
+struct c_matrix_traits {
+    typedef T type [N] [M];
+};
+
+template<class T, int N>
+struct initialize_c_vector  {
+    void operator () (typename c_vector_traits<T, N>::type &v) {
+        for (int i = 0; i < N; ++ i)
+            v [i] = std::rand () * 1.f;
+//            v [i] = 0.f;
+        }
+};
+template<class V>
+BOOST_UBLAS_INLINE
+void initialize_vector (V &v) {
+    int size = v.size ();
+    for (int i = 0; i < size; ++ i)
+        v [i] = std::rand () * 1.f;
+//        v [i] = 0.f;
+}
+
+template<class T, int N, int M>
+struct initialize_c_matrix  {
+    void operator () (typename c_matrix_traits<T, N, M>::type &m) {
+        for (int i = 0; i < N; ++ i)
+            for (int j = 0; j < M; ++ j)
+                m [i] [j] = std::rand () * 1.f;
+//                m [i] [j] = 0.f;
+    }
+};
+template<class M>
+BOOST_UBLAS_INLINE
+void initialize_matrix (M &m, ublas::row_major_tag) {
+    int size1 = m.size1 ();
+    int size2 = m.size2 ();
+    for (int i = 0; i < size1; ++ i)
+        for (int j = 0; j < size2; ++ j)
+            m (i, j) = std::rand () * 1.f;
+//            m (i, j) = 0.f;
+}
+template<class M>
+BOOST_UBLAS_INLINE
+void initialize_matrix (M &m, ublas::column_major_tag) {
+    int size1 = m.size1 ();
+    int size2 = m.size2 ();
+    for (int j = 0; j < size2; ++ j)
+        for (int i = 0; i < size1; ++ i)
+            m (i, j) = std::rand () * 1.f;
+//            m (i, j) = 0.f;
+}
+template<class M>
+BOOST_UBLAS_INLINE
+void initialize_matrix (M &m) {
+    typedef typename M::orientation_category orientation_category;
+    initialize_matrix (m, orientation_category ());
+}
+
+template<class T>
+BOOST_UBLAS_INLINE
+void sink_scalar (const T &s) {
+    static T g_s = s;
+}
+
+template<class T, int N>
+struct sink_c_vector {
+    void operator () (const typename c_vector_traits<T, N>::type &v) {
+        static typename c_vector_traits<T, N>::type g_v;
+        for (int i = 0; i < N; ++ i)
+            g_v [i] = v [i];
+    }
+};
+template<class V>
+BOOST_UBLAS_INLINE
+void sink_vector (const V &v) {
+    static V g_v (v);
+}
+
+template<class T, int N, int M>
+struct sink_c_matrix {
+    void operator () (const typename c_matrix_traits<T, N, M>::type &m) {
+    static typename c_matrix_traits<T, N, M>::type g_m;
+    for (int i = 0; i < N; ++ i)
+        for (int j = 0; j < M; ++ j)
+            g_m [i] [j] = m [i] [j];
+    }
+};
+template<class M>
+BOOST_UBLAS_INLINE
+void sink_matrix (const M &m) {
+    static M g_m (m);
+}
+
+template<class T>
+struct peak {
+    void operator () (int runs);
+};
+
+template<class T, int N>
+struct bench_1 {
+    void operator () (int runs);
+};
+
+template<class T, int N>
+struct bench_2 {
+    void operator () (int runs);
+};
+
+template<class T, int N>
+struct bench_3 {
+    void operator () (int runs);
+};
+
+struct safe_tag {};
+struct fast_tag {};
+
+// #define USE_FLOAT
+#define USE_DOUBLE
+// #define USE_STD_COMPLEX
+
+#define USE_MAP_ARRAY
+// #define USE_STD_MAP
+// #define USE_STD_VALARRAY
+
+#define USE_MAPPED_VECTOR
+#define USE_COMPRESSED_VECTOR
+#define USE_COORDINATE_VECTOR
+
+#define USE_MAPPED_MATRIX
+// #define USE_SPARSE_VECTOR_OF_SPARSE_VECTOR
+#define USE_COMPRESSED_MATRIX
+#define USE_COORDINATE_MATRIX
+
+#endif
diff --git a/benchmarks/bench2/bench21.cpp b/benchmarks/bench2/bench21.cpp
new file mode 100644
index 0000000..50d70a4
--- /dev/null
+++ b/benchmarks/bench2/bench21.cpp
@@ -0,0 +1,282 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench2.hpp"
+
+template<class T, int N>
+struct bench_c_inner_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_vector_traits<T, N>::type v1, v2;
+            initialize_c_vector<T, N> () (v1);
+            initialize_c_vector<T, N> () (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                static value_type s (0);
+                for (int j = 0; j < N; ++ j) {
+                    s += v1 [j] * v2 [j];
+                }
+//                sink_scalar (s);
+            }
+            footer<value_type> () (N, N - 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_my_inner_prod {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static V v1 (N, N), v2 (N, N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                static value_type s (0);
+                s = ublas::inner_prod (v1, v2);
+//                sink_scalar (s);
+                BOOST_UBLAS_NOT_USED(s);
+            }
+            footer<value_type> () (N, N - 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_cpp_inner_prod {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static V v1 (N), v2 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                static value_type s (0);
+                s = (v1 * v2).sum ();
+//                sink_scalar (s);
+            }
+            footer<value_type> () (N, N - 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T, int N>
+struct bench_c_vector_add {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_vector_traits<T, N>::type v1, v2, v3;
+            initialize_c_vector<T, N> () (v1);
+            initialize_c_vector<T, N> () (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    v3 [j] = - (v1 [j] + v2 [j]);
+                }
+//                sink_c_vector<T, N> () (v3);
+                BOOST_UBLAS_NOT_USED(v3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_my_vector_add {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static V v1 (N, N), v2 (N, N), v3 (N, N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v3 = - (v1 + v2);
+//                sink_vector (v3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static V v1 (N, N), v2 (N, N), v3 (N, N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v3.assign (- (v1 + v2));
+//                sink_vector (v3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_cpp_vector_add {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static V v1 (N), v2 (N), v3 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v3 = - (v1 + v2);
+//                sink_vector (v3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+// Benchmark O (n)
+template<class T, int N>
+void bench_1<T, N>::operator () (int runs) {
+    header ("bench_1");
+
+    header ("inner_prod");
+
+    header ("C array");
+    bench_c_inner_prod<T, N> () (runs);
+
+#ifdef USE_MAPPED_VECTOR
+#ifdef USE_MAP_ARRAY
+    header ("mapped_vector<map_array>");
+    bench_my_inner_prod<ublas::mapped_vector<T, ublas::map_array<std::size_t, T> >, N> () (runs);
+#endif
+
+#ifdef USE_STD_MAP
+    header ("mapped_vector<std::map>");
+    bench_my_inner_prod<ublas::mapped_vector<T, std::map<std::size_t, T> >, N> () (runs);
+#endif
+#endif
+
+#ifdef USE_COMPRESSED_VECTOR
+    header ("compressed_vector");
+    bench_my_inner_prod<ublas::compressed_vector<T>, N> () (runs);
+#endif
+
+#ifdef USE_COORDINATE_VECTOR
+    header ("coordinate_vector");
+    bench_my_inner_prod<ublas::coordinate_vector<T>, N> () (runs);
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_inner_prod<std::valarray<T>, N> () (runs);
+#endif
+
+    header ("vector + vector");
+
+    header ("C array");
+    bench_c_vector_add<T, N> () (runs);
+
+#ifdef USE_MAPPED_VECTOR
+#ifdef USE_MAP_ARRAY
+    header ("mapped_vector<map_array> safe");
+    bench_my_vector_add<ublas::mapped_vector<T, ublas::map_array<std::size_t, T> >, N> () (runs, safe_tag ());
+
+    header ("maped_vector<map_array> fast");
+    bench_my_vector_add<ublas::mapped_vector<T, ublas::map_array<std::size_t, T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_MAP
+    header ("mapped_vector<std::map> safe");
+    bench_my_vector_add<ublas::mapped_vector<T, std::map<std::size_t, T> >, N> () (runs, safe_tag ());
+
+    header ("mapped_vector<std::map> fast");
+    bench_my_vector_add<ublas::mapped_vector<T, std::map<std::size_t, T> >, N> () (runs, fast_tag ());
+#endif
+#endif
+
+#ifdef USE_COMPRESSED_VECTOR
+#ifdef USE_MAP_ARRAY
+    header ("compressed_vector safe");
+    bench_my_vector_add<ublas::compressed_vector<T>, N> () (runs, safe_tag ());
+
+    header ("compressed_vector fast");
+    bench_my_vector_add<ublas::compressed_vector<T>, N> () (runs, fast_tag ());
+#endif
+#endif
+
+#ifdef USE_COORDINATE_VECTOR
+#ifdef USE_MAP_ARRAY
+    header ("coordinate_vector safe");
+    bench_my_vector_add<ublas::coordinate_vector<T>, N> () (runs, safe_tag ());
+
+    header ("coordinate_vector fast");
+    bench_my_vector_add<ublas::coordinate_vector<T>, N> () (runs, fast_tag ());
+#endif
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_vector_add<std::valarray<T>, N> () (runs);
+#endif
+}
+
+#ifdef USE_FLOAT
+template struct bench_1<float, 3>;
+template struct bench_1<float, 10>;
+template struct bench_1<float, 30>;
+template struct bench_1<float, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_1<double, 3>;
+template struct bench_1<double, 10>;
+template struct bench_1<double, 30>;
+template struct bench_1<double, 100>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_1<std::complex<float>, 3>;
+template struct bench_1<std::complex<float>, 10>;
+template struct bench_1<std::complex<float>, 30>;
+template struct bench_1<std::complex<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_1<std::complex<double>, 3>;
+template struct bench_1<std::complex<double>, 10>;
+template struct bench_1<std::complex<double>, 30>;
+template struct bench_1<std::complex<double>, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench2/bench22.cpp b/benchmarks/bench2/bench22.cpp
new file mode 100644
index 0000000..f40df79
--- /dev/null
+++ b/benchmarks/bench2/bench22.cpp
@@ -0,0 +1,469 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench2.hpp"
+
+template<class T, int N>
+struct bench_c_outer_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m;
+            static typename c_vector_traits<T, N>::type v1, v2;
+            initialize_c_vector<T, N> () (v1);
+            initialize_c_vector<T, N> () (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m [j] [k] = - v1 [j] * v2 [k];
+                    }
+                }
+//                sink_c_matrix<T, N, N> () (m);
+                BOOST_UBLAS_NOT_USED(m);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_my_outer_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m (N, N, N * N);
+            static V v1 (N, N), v2 (N, N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m = - ublas::outer_prod (v1, v2);
+//                sink_matrix (m);
+                BOOST_UBLAS_NOT_USED(m);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m (N, N, N * N);
+            static V v1 (N, N), v2 (N, N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m.assign (- ublas::outer_prod (v1, v2));
+//                sink_matrix (m);
+                BOOST_UBLAS_NOT_USED(m);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_cpp_outer_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m (N * N);
+            static V v1 (N), v2 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m [N * j + k] = - v1 [j] * v2 [k];
+                    }
+                }
+//                sink_vector (m);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T, int N>
+struct bench_c_matrix_vector_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m;
+            static typename c_vector_traits<T, N>::type v1, v2;
+            initialize_c_matrix<T, N, N> () (m);
+            initialize_c_vector<T, N> () (v1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    v2 [j] = 0;
+                    for (int k = 0; k < N; ++ k) {
+                        v2 [j] += m [j] [k] * v1 [k];
+                    }
+                }
+//                sink_c_vector<T, N> () (v2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_my_matrix_vector_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m (N, N, N * N);
+            static V v1 (N, N), v2 (N, N);
+            initialize_matrix (m);
+            initialize_vector (v1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v2 = ublas::prod (m, v1);
+//                sink_vector (v2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m (N, N, N * N);
+            static V v1 (N, N), v2 (N, N);
+            initialize_matrix (m);
+            initialize_vector (v1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v2.assign (ublas::prod (m, v1));
+//                sink_vector (v2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_cpp_matrix_vector_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m (N * N);
+            static V v1 (N), v2 (N);
+            initialize_vector (m);
+            initialize_vector (v1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    std::valarray<value_type> row (m [std::slice (N * j, N, 1)]);
+                    v2 [j] = (row * v1).sum ();
+                }
+//                sink_vector (v2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T, int N>
+struct bench_c_matrix_add {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m1, m2, m3;
+            initialize_c_matrix<T, N, N> () (m1);
+            initialize_c_matrix<T, N, N> () (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m3 [j] [k] = - (m1 [j] [k] + m2 [j] [k]);
+                    }
+                }
+//                sink_c_matrix<T, N, N> () (m3);
+                BOOST_UBLAS_NOT_USED(m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_my_matrix_add {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m1 (N, N, N * N), m2 (N, N, N * N), m3 (N, N, N * N);
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3 = - (m1 + m2);
+//                sink_matrix (m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m1 (N, N, N * N), m2 (N, N, N * N), m3 (N, N, N * N);
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3.assign (- (m1 + m2));
+//                sink_matrix (m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_cpp_matrix_add {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m1 (N * N), m2 (N * N), m3 (N * N);
+            initialize_vector (m1);
+            initialize_vector (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3 = - (m1 + m2);
+//                sink_vector (m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+// Benchmark O (n ^ 2)
+template<class T, int N>
+void bench_2<T, N>::operator () (int runs) {
+    header ("bench_2");
+
+    header ("outer_prod");
+
+    header ("C array");
+    bench_c_outer_prod<T, N> () (runs);
+
+#ifdef USE_SPARSE_MATRIX
+#ifdef USE_MAP_ARRAY
+    header ("sparse_matrix<map_array>, sparse_vector<map_array> safe");
+    bench_my_outer_prod<ublas::sparse_matrix<T, ublas::row_major, ublas::map_array<std::size_t, T> >,
+                        ublas::sparse_vector<T, ublas::map_array<std::size_t, T> >, N> () (runs, safe_tag ());
+
+    header ("sparse_matrix<map_array>, sparse_vector<map_array> fast");
+    bench_my_outer_prod<ublas::sparse_matrix<T, ublas::row_major, ublas::map_array<std::size_t, T> >,
+                        ublas::sparse_vector<T, ublas::map_array<std::size_t, T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_MAP
+    header ("sparse_matrix<std::map>, sparse_vector<std::map> safe");
+    bench_my_outer_prod<ublas::sparse_matrix<T, ublas::row_major, std::map<std::size_t, T> >,
+                        ublas::sparse_vector<T, std::map<std::size_t, T> >, N> () (runs, safe_tag ());
+
+    header ("sparse_matrix<std::map>, sparse_vector<std::map> fast");
+    bench_my_outer_prod<ublas::sparse_matrix<T, ublas::row_major, std::map<std::size_t, T> >,
+                        ublas::sparse_vector<T, std::map<std::size_t, T> >, N> () (runs, fast_tag ());
+#endif
+#endif
+
+#ifdef USE_COMPRESSED_MATRIX
+    header ("compressed_matrix, compressed_vector safe");
+    bench_my_outer_prod<ublas::compressed_matrix<T, ublas::row_major>,
+                        ublas::compressed_vector<T>, N> () (runs, safe_tag ());
+
+    header ("compressed_matrix, compressed_vector fast");
+    bench_my_outer_prod<ublas::compressed_matrix<T, ublas::row_major>,
+                        ublas::compressed_vector<T>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_COORDINATE_MATRIX
+    header ("coordinate_matrix, coordinate_vector safe");
+    bench_my_outer_prod<ublas::coordinate_matrix<T, ublas::row_major>,
+                        ublas::coordinate_vector<T>, N> () (runs, safe_tag ());
+
+    header ("coordinate_matrix, coordinate_vector fast");
+    bench_my_outer_prod<ublas::coordinate_matrix<T, ublas::row_major>,
+                        ublas::coordinate_vector<T>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_outer_prod<std::valarray<T>, std::valarray<T>, N> () (runs);
+#endif
+
+    header ("prod (matrix, vector)");
+
+    header ("C array");
+    bench_c_matrix_vector_prod<T, N> () (runs);
+
+#ifdef USE_SPARSE_MATRIX
+#ifdef USE_MAP_ARRAY
+    header ("sparse_matrix<map_array>, sparse_vector<map_array> safe");
+    bench_my_matrix_vector_prod<ublas::sparse_matrix<T, ublas::row_major, ublas::map_array<std::size_t, T> >,
+                                ublas::sparse_vector<T, ublas::map_array<std::size_t, T> >, N> () (runs, safe_tag ());
+
+    header ("sparse_matrix<map_array>, sparse_vector<map_array> fast");
+    bench_my_matrix_vector_prod<ublas::sparse_matrix<T, ublas::row_major, ublas::map_array<std::size_t, T> >,
+                                ublas::sparse_vector<T, ublas::map_array<std::size_t, T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_MAP
+    header ("sparse_matrix<std::map>, sparse_vector<std::map> safe");
+    bench_my_matrix_vector_prod<ublas::sparse_matrix<T, ublas::row_major, std::map<std::size_t, T> >,
+                                ublas::sparse_vector<T, std::map<std::size_t, T> >, N> () (runs, safe_tag ());
+
+    header ("sparse_matrix<std::map>, sparse_vector<std::map> fast");
+    bench_my_matrix_vector_prod<ublas::sparse_matrix<T, ublas::row_major, std::map<std::size_t, T> >,
+                                ublas::sparse_vector<T, std::map<std::size_t, T> >, N> () (runs, fast_tag ());
+#endif
+#endif
+
+#ifdef USE_COMPRESSED_MATRIX
+    header ("compressed_matrix, compressed_vector safe");
+    bench_my_matrix_vector_prod<ublas::compressed_matrix<T, ublas::row_major>,
+                                ublas::compressed_vector<T>, N> () (runs, safe_tag ());
+
+    header ("compressed_matrix, compressed_vector fast");
+    bench_my_matrix_vector_prod<ublas::compressed_matrix<T, ublas::row_major>,
+                                ublas::compressed_vector<T>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_COORDINATE_MATRIX
+    header ("coordinate_matrix, coordinate_vector safe");
+    bench_my_matrix_vector_prod<ublas::coordinate_matrix<T, ublas::row_major>,
+                                ublas::coordinate_vector<T>, N> () (runs, safe_tag ());
+
+    header ("coordinate_matrix, coordinate_vector fast");
+    bench_my_matrix_vector_prod<ublas::coordinate_matrix<T, ublas::row_major>,
+                                ublas::coordinate_vector<T>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_matrix_vector_prod<std::valarray<T>, std::valarray<T>, N> () (runs);
+#endif
+
+    header ("matrix + matrix");
+
+    header ("C array");
+    bench_c_matrix_add<T, N> () (runs);
+
+#ifdef USE_SPARSE_MATRIX
+#ifdef USE_MAP_ARRAY
+    header ("sparse_matrix<map_array> safe");
+    bench_my_matrix_add<ublas::sparse_matrix<T, ublas::row_major, ublas::map_array<std::size_t, T> >, N> () (runs, safe_tag ());
+
+    header ("sparse_matrix<map_array> fast");
+    bench_my_matrix_add<ublas::sparse_matrix<T, ublas::row_major, ublas::map_array<std::size_t, T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_MAP
+    header ("sparse_matrix<std::map> safe");
+    bench_my_matrix_add<ublas::sparse_matrix<T, ublas::row_major, std::map<std::size_t, T> >, N> () (runs, safe_tag ());
+
+    header ("sparse_matrix<std::map> fast");
+    bench_my_matrix_add<ublas::sparse_matrix<T, ublas::row_major, std::map<std::size_t, T> >, N> () (runs, fast_tag ());
+#endif
+#endif
+
+#ifdef USE_COMPRESSED_MATRIX
+    header ("compressed_matrix safe");
+    bench_my_matrix_add<ublas::compressed_matrix<T, ublas::row_major>, N> () (runs, safe_tag ());
+
+    header ("compressed_matrix fast");
+    bench_my_matrix_add<ublas::compressed_matrix<T, ublas::row_major>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_COORDINATE_MATRIX
+    header ("coordinate_matrix safe");
+    bench_my_matrix_add<ublas::coordinate_matrix<T, ublas::row_major>, N> () (runs, safe_tag ());
+
+    header ("coordinate_matrix fast");
+    bench_my_matrix_add<ublas::coordinate_matrix<T, ublas::row_major>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_matrix_add<std::valarray<T>, N> () (runs);
+#endif
+}
+
+#ifdef USE_FLOAT
+template struct bench_2<float, 3>;
+template struct bench_2<float, 10>;
+template struct bench_2<float, 30>;
+template struct bench_2<float, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_2<double, 3>;
+template struct bench_2<double, 10>;
+template struct bench_2<double, 30>;
+template struct bench_2<double, 100>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_2<std::complex<float>, 3>;
+template struct bench_2<std::complex<float>, 10>;
+template struct bench_2<std::complex<float>, 30>;
+template struct bench_2<std::complex<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_2<std::complex<double>, 3>;
+template struct bench_2<std::complex<double>, 10>;
+template struct bench_2<std::complex<double>, 30>;
+template struct bench_2<std::complex<double>, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench2/bench23.cpp b/benchmarks/bench2/bench23.cpp
new file mode 100644
index 0000000..bb363f5
--- /dev/null
+++ b/benchmarks/bench2/bench23.cpp
@@ -0,0 +1,196 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench2.hpp"
+
+template<class T, int N>
+struct bench_c_matrix_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m1, m2, m3;
+            initialize_c_matrix<T, N, N> () (m1);
+            initialize_c_matrix<T, N, N> () (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m3 [j] [k] = 0;
+                        for (int l = 0; l < N; ++ l) {
+                            m3 [j] [k] += m1 [j] [l] * m2 [l] [k];
+                        }
+                    }
+                }
+//                sink_c_matrix<T, N, N> () (m3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M1, class M2, int N>
+struct bench_my_matrix_prod {
+    typedef typename M1::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M1 m1 (N, N, N * N), m3 (N, N, N * N);
+            static M2 m2 (N, N, N * N);
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3 = ublas::prod (m1, m2);
+//                sink_matrix (m3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M1 m1 (N, N, N * N), m3 (N, N, N * N);
+            static M2 m2 (N, N, N * N);
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3.assign (ublas::prod (m1, m2));
+//                sink_matrix (m3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_cpp_matrix_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m1 (N * N), m2 (N * N), m3 (N * N);
+            initialize_vector (m1);
+            initialize_vector (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    std::valarray<value_type> row (m1 [std::slice (N * j, N, 1)]);
+                    for (int k = 0; k < N; ++ k) {
+                        std::valarray<value_type> column (m2 [std::slice (k, N, N)]);
+                        m3 [N * j + k] = (row * column).sum ();
+                    }
+                }
+//                sink_vector (m3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+// Benchmark O (n ^ 3)
+template<class T, int N>
+void bench_3<T, N>::operator () (int runs) {
+    header ("bench_3");
+
+    header ("prod (matrix, matrix)");
+
+    header ("C array");
+    bench_c_matrix_prod<T, N> () (runs);
+
+#ifdef USE_SPARSE_MATRIX
+#ifdef USE_MAP_ARRAY
+    header ("sparse_matrix<row_major, map_array>, sparse_matrix<column_major, map_array> safe");
+    bench_my_matrix_prod<ublas::sparse_matrix<T, ublas::row_major, ublas::map_array<std::size_t, T> >,
+                         ublas::sparse_matrix<T, ublas::column_major, ublas::map_array<std::size_t, T> >, N> () (runs, safe_tag ());
+
+    header ("sparse_matrix<row_major, map_array>, sparse_matrix<column_major, map_array> fast");
+    bench_my_matrix_prod<ublas::sparse_matrix<T, ublas::row_major, ublas::map_array<std::size_t, T> >,
+                         ublas::sparse_matrix<T, ublas::column_major, ublas::map_array<std::size_t, T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_MAP
+    header ("sparse_matrix<row_major, std::map>, sparse_matrix<column_major, std::map> safe");
+    bench_my_matrix_prod<ublas::sparse_matrix<T, ublas::row_major, std::map<std::size_t, T> >,
+                         ublas::sparse_matrix<T, ublas::column_major, std::map<std::size_t, T> >, N> () (runs, safe_tag ());
+
+    header ("sparse_matrix<row_major, std::map>, sparse_matrix<column_major, std::map> fast");
+    bench_my_matrix_prod<ublas::sparse_matrix<T, ublas::row_major, std::map<std::size_t, T> >,
+                         ublas::sparse_matrix<T, ublas::column_major, std::map<std::size_t, T> >, N> () (runs, fast_tag ());
+#endif
+#endif
+
+#ifdef USE_COMPRESSED_MATRIX
+    header ("compressed_matrix<row_major>, compressed_matrix<column_major> safe");
+    bench_my_matrix_prod<ublas::compressed_matrix<T, ublas::row_major>,
+                         ublas::compressed_matrix<T, ublas::column_major>, N> () (runs, safe_tag ());
+
+    header ("compressed_matrix<row_major>, compressed_matrix<column_major> fast");
+    bench_my_matrix_prod<ublas::compressed_matrix<T, ublas::row_major>,
+                         ublas::compressed_matrix<T, ublas::column_major>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_COORDINATE_MATRIX
+    header ("coordinate_matrix<row_major>, coordinate_matrix<column_major> safe");
+    bench_my_matrix_prod<ublas::coordinate_matrix<T, ublas::row_major>,
+                         ublas::coordinate_matrix<T, ublas::column_major>, N> () (runs, safe_tag ());
+
+    header ("coordinate_matrix<row_major>, coordinate_matrix<column_major> fast");
+    bench_my_matrix_prod<ublas::coordinate_matrix<T, ublas::row_major>,
+                         ublas::coordinate_matrix<T, ublas::column_major>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_matrix_prod<std::valarray<T>, N> () (runs);
+#endif
+}
+
+#ifdef USE_FLOAT
+template struct bench_3<float, 3>;
+template struct bench_3<float, 10>;
+template struct bench_3<float, 30>;
+template struct bench_3<float, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_3<double, 3>;
+template struct bench_3<double, 10>;
+template struct bench_3<double, 30>;
+template struct bench_3<double, 100>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_3<std::complex<float>, 3>;
+template struct bench_3<std::complex<float>, 10>;
+template struct bench_3<std::complex<float>, 30>;
+template struct bench_3<std::complex<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_3<std::complex<double>, 3>;
+template struct bench_3<std::complex<double>, 10>;
+template struct bench_3<std::complex<double>, 30>;
+template struct bench_3<std::complex<double>, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench3/Jamfile.v2 b/benchmarks/bench3/Jamfile.v2
new file mode 100644
index 0000000..7ce9c9b
--- /dev/null
+++ b/benchmarks/bench3/Jamfile.v2
@@ -0,0 +1,10 @@
+# Copyright (c) 2004 Michael Stevens
+# Use, modification and distribution are subject to the
+# Boost Software License, Version 1.0. (See accompanying file
+# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# bench3 - measure the performance of vector and matrix proxy's operations.
+
+exe bench3
+    : bench3.cpp bench31.cpp bench32.cpp bench33.cpp
+    ;
diff --git a/benchmarks/bench3/bench3.cpp b/benchmarks/bench3/bench3.cpp
new file mode 100644
index 0000000..390d226
--- /dev/null
+++ b/benchmarks/bench3/bench3.cpp
@@ -0,0 +1,122 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench3.hpp"
+
+void header (std::string text) {
+    std::cout << text << std::endl;
+}
+
+template<class T>
+struct peak_c_plus {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static T s (0);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                s += T (0);
+//                sink_scalar (s);
+            }
+            footer<value_type> () (0, 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class T>
+struct peak_c_multiplies {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static T s (1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                s *= T (1);
+//                sink_scalar (s);
+            }
+            footer<value_type> () (0, 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T>
+void peak<T>::operator () (int runs) {
+    header ("peak");
+
+    header ("plus");
+    peak_c_plus<T> () (runs);
+
+    header ("multiplies");
+    peak_c_multiplies<T> () (runs);
+}
+
+
+template <typename scalar> 
+void do_bench (std::string type_string, int scale)
+{
+    header (type_string);
+    peak<scalar> () (1000000 * scale);
+
+    header (type_string + ", 3");
+    bench_1<scalar, 3> () (1000000 * scale);
+    bench_2<scalar, 3> () (300000 * scale);
+    bench_3<scalar, 3> () (100000 * scale);
+
+    header (type_string + ", 10");
+    bench_1<scalar, 10> () (300000 * scale);
+    bench_2<scalar, 10> () (30000 * scale);
+    bench_3<scalar, 10> () (3000 * scale);
+
+    header (type_string + ", 30");
+    bench_1<scalar, 30> () (100000 * scale);
+    bench_2<scalar, 30> () (3000 * scale);
+    bench_3<scalar, 30> () (100 * scale);
+
+    header (type_string + ", 100");
+    bench_1<scalar, 100> () (30000 * scale);
+    bench_2<scalar, 100> () (300 * scale);
+    bench_3<scalar, 100> () (3 * scale);
+}
+
+int main (int argc, char *argv []) {
+
+    int scale = 1;
+    if (argc > 1)
+        scale = std::atoi (argv [1]);
+
+#ifdef USE_FLOAT
+    do_bench<float> ("FLOAT", scale);
+#endif
+
+#ifdef USE_DOUBLE
+    do_bench<double> ("DOUBLE", scale);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    do_bench<std::complex<float> > ("COMPLEX<FLOAT>", scale);
+#endif
+
+#ifdef USE_DOUBLE
+    do_bench<std::complex<double> > ("COMPLEX<DOUBLE>", scale);
+#endif
+#endif
+
+    return 0;
+}
diff --git a/benchmarks/bench3/bench3.hpp b/benchmarks/bench3/bench3.hpp
new file mode 100644
index 0000000..5b64b59
--- /dev/null
+++ b/benchmarks/bench3/bench3.hpp
@@ -0,0 +1,159 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef BENCH3_H
+#define BENCH3_H
+
+#include <iostream>
+#include <string>
+#include <valarray>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+
+#include <boost/timer.hpp>
+
+
+#define BOOST_UBLAS_NOT_USED(x) (void)(x)
+
+
+namespace ublas = boost::numeric::ublas;
+
+void header (std::string text);
+
+template<class T>
+struct footer {
+    void operator () (int multiplies, int plus, int runs, double elapsed) {
+        std::cout << "elapsed: " << elapsed << " s, "
+                  << (multiplies * ublas::type_traits<T>::multiplies_complexity +
+                      plus * ublas::type_traits<T>::plus_complexity) * runs /
+                     (1024 * 1024 * elapsed) << " Mflops" << std::endl;
+    }
+};
+
+template<class T, int N>
+struct c_vector_traits {
+    typedef T type [N];
+};
+template<class T, int N, int M>
+struct c_matrix_traits {
+    typedef T type [N] [M];
+};
+
+template<class T, int N>
+struct initialize_c_vector  {
+    void operator () (typename c_vector_traits<T, N>::type &v) {
+        for (int i = 0; i < N; ++ i)
+            v [i] = std::rand () * 1.f;
+//            v [i] = 0.f;
+        }
+};
+template<class V>
+BOOST_UBLAS_INLINE
+void initialize_vector (V &v) {
+    int size = v.size ();
+    for (int i = 0; i < size; ++ i)
+        v [i] = std::rand () * 1.f;
+//      v [i] = 0.f;
+}
+
+template<class T, int N, int M>
+struct initialize_c_matrix  {
+    void operator () (typename c_matrix_traits<T, N, M>::type &m) {
+        for (int i = 0; i < N; ++ i)
+            for (int j = 0; j < M; ++ j)
+                m [i] [j] = std::rand () * 1.f;
+//                m [i] [j] = 0.f;
+    }
+};
+template<class M>
+BOOST_UBLAS_INLINE
+void initialize_matrix (M &m) {
+    int size1 = m.size1 ();
+    int size2 = m.size2 ();
+    for (int i = 0; i < size1; ++ i)
+        for (int j = 0; j < size2; ++ j)
+            m (i, j) = std::rand () * 1.f;
+//            m (i, j) = 0.f;
+}
+
+template<class T>
+BOOST_UBLAS_INLINE
+void sink_scalar (const T &s) {
+    static T g_s = s;
+}
+
+template<class T, int N>
+struct sink_c_vector {
+    void operator () (const typename c_vector_traits<T, N>::type &v) {
+        static typename c_vector_traits<T, N>::type g_v;
+        for (int i = 0; i < N; ++ i)
+            g_v [i] = v [i];
+    }
+};
+template<class V>
+BOOST_UBLAS_INLINE
+void sink_vector (const V &v) {
+    static V g_v (v);
+}
+
+template<class T, int N, int M>
+struct sink_c_matrix {
+    void operator () (const typename c_matrix_traits<T, N, M>::type &m) {
+    static typename c_matrix_traits<T, N, M>::type g_m;
+    for (int i = 0; i < N; ++ i)
+        for (int j = 0; j < M; ++ j)
+            g_m [i] [j] = m [i] [j];
+    }
+};
+template<class M>
+BOOST_UBLAS_INLINE
+void sink_matrix (const M &m) {
+    static M g_m (m);
+}
+
+template<class T>
+struct peak {
+    void operator () (int runs);
+};
+
+template<class T, int N>
+struct bench_1 {
+    void operator () (int runs);
+};
+
+template<class T, int N>
+struct bench_2 {
+    void operator () (int runs);
+};
+
+template<class T, int N>
+struct bench_3 {
+    void operator () (int runs);
+};
+
+struct safe_tag {};
+struct fast_tag {};
+
+// #define USE_FLOAT
+#define USE_DOUBLE
+// #define USE_STD_COMPLEX
+
+#define USE_C_ARRAY
+// #define USE_BOUNDED_ARRAY
+#define USE_UNBOUNDED_ARRAY
+// #define USE_STD_VALARRAY
+#define USE_STD_VECTOR
+
+#endif
diff --git a/benchmarks/bench3/bench31.cpp b/benchmarks/bench3/bench31.cpp
new file mode 100644
index 0000000..9181eb1
--- /dev/null
+++ b/benchmarks/bench3/bench31.cpp
@@ -0,0 +1,296 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench3.hpp"
+
+template<class T, int N>
+struct bench_c_inner_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_vector_traits<T, N>::type v1, v2;
+            initialize_c_vector<T, N> () (v1);
+            initialize_c_vector<T, N> () (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                static value_type s (0);
+                for (int j = 0; j < N; ++ j) {
+                    s += v1 [j] * v2 [j];
+                }
+//                sink_scalar (s);
+            }
+            footer<value_type> () (N, N - 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_my_inner_prod {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static V v1 (N), v2 (N);
+            ublas::vector_range<V> vr1 (v1, ublas::range (0, N)),
+                                   vr2 (v2, ublas::range (0, N));
+            initialize_vector (vr1);
+            initialize_vector (vr2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                static value_type s (0);
+                s = ublas::inner_prod (vr1, vr2);
+//                sink_scalar (s);
+                BOOST_UBLAS_NOT_USED(s);
+            }
+            footer<value_type> () (N, N - 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_cpp_inner_prod {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static V v1 (N), v2 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                static value_type s (0);
+                s = (v1 * v2).sum ();
+//                sink_scalar (s);
+            }
+            footer<value_type> () (N, N - 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T, int N>
+struct bench_c_vector_add {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_vector_traits<T, N>::type v1, v2, v3;
+            initialize_c_vector<T, N> () (v1);
+            initialize_c_vector<T, N> () (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    v3 [j] = - (v1 [j] + v2 [j]);
+                }
+//                sink_c_vector<T, N> () (v3);
+                BOOST_UBLAS_NOT_USED(v3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_my_vector_add {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static V v1 (N), v2 (N), v3 (N);
+            ublas::vector_range<V> vr1 (v1, ublas::range (0, N)),
+                                   vr2 (v2, ublas::range (0, N)),
+                                   vr3 (v2, ublas::range (0, N));
+            initialize_vector (vr1);
+            initialize_vector (vr2);
+            initialize_vector (vr3);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                vr3 = - (vr1 + vr2);
+//                sink_vector (vr3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static V v1 (N), v2 (N), v3 (N);
+            ublas::vector_range<V> vr1 (v1, ublas::range (0, N)),
+                                   vr2 (v2, ublas::range (0, N)),
+                                   vr3 (v2, ublas::range (0, N));
+            initialize_vector (vr1);
+            initialize_vector (vr2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                vr3.assign (- (vr1 + vr2));
+//                sink_vector (vr3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class V, int N>
+struct bench_cpp_vector_add {
+    typedef typename V::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static V v1 (N), v2 (N), v3 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                v3 = - (v1 + v2);
+//                sink_vector (v3);
+            }
+            footer<value_type> () (0, 2 * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+// Benchmark O (n)
+template<class T, int N>
+void bench_1<T, N>::operator () (int runs) {
+    header ("bench_1");
+
+    header ("inner_prod");
+
+    header ("C array");
+    bench_c_inner_prod<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_vector");
+    bench_my_inner_prod<ublas::c_vector<T, N>, N> () (runs);
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("vector<bounded_array>");
+    bench_my_inner_prod<ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs);
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("vector<unbounded_array>");
+    bench_my_inner_prod<ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs);
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("vector<std::valarray>");
+    bench_my_inner_prod<ublas::vector<T, std::valarray<T> >, N> () ();
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("vector<std::vector>");
+    bench_my_inner_prod<ublas::vector<T, std::vector<T> >, N> () (runs);
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_inner_prod<std::valarray<T>, N> () (runs);
+#endif
+
+    header ("vector + vector");
+
+    header ("C array");
+    bench_c_vector_add<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_vector safe");
+    bench_my_vector_add<ublas::c_vector<T, N>, N> () (runs, safe_tag ());
+
+    header ("c_vector fast");
+    bench_my_vector_add<ublas::c_vector<T, N>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("vector<bounded_array> safe");
+    bench_my_vector_add<ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, safe_tag ());
+
+    header ("vector<bounded_array> fast");
+    bench_my_vector_add<ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("vector<unbounded_array> safe");
+    bench_my_vector_add<ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, safe_tag ());
+
+    header ("vector<unbounded_array> fast");
+    bench_my_vector_add<ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("vector<std::valarray> safe");
+    bench_my_vector_add<ublas::vector<T, std::valarray<T> >, N> () (runs, safe_tag ());
+
+    header ("vector<std::valarray> fast");
+    bench_my_vector_add<ublas::vector<T, std::valarray<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("vector<std::vector> safe");
+    bench_my_vector_add<ublas::vector<T, std::vector<T> >, N> () (runs, safe_tag ());
+
+    header ("vector<std::vector> fast");
+    bench_my_vector_add<ublas::vector<T, std::vector<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_vector_add<std::valarray<T>, N> () (runs);
+#endif
+}
+
+#ifdef USE_FLOAT
+template struct bench_1<float, 3>;
+template struct bench_1<float, 10>;
+template struct bench_1<float, 30>;
+template struct bench_1<float, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_1<double, 3>;
+template struct bench_1<double, 10>;
+template struct bench_1<double, 30>;
+template struct bench_1<double, 100>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_1<std::complex<float>, 3>;
+template struct bench_1<std::complex<float>, 10>;
+template struct bench_1<std::complex<float>, 30>;
+template struct bench_1<std::complex<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_1<std::complex<double>, 3>;
+template struct bench_1<std::complex<double>, 10>;
+template struct bench_1<std::complex<double>, 30>;
+template struct bench_1<std::complex<double>, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench3/bench32.cpp b/benchmarks/bench3/bench32.cpp
new file mode 100644
index 0000000..3819090
--- /dev/null
+++ b/benchmarks/bench3/bench32.cpp
@@ -0,0 +1,501 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench3.hpp"
+
+template<class T, int N>
+struct bench_c_outer_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m;
+            static typename c_vector_traits<T, N>::type v1, v2;
+            initialize_c_vector<T, N> () (v1);
+            initialize_c_vector<T, N> () (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m [j] [k] = - v1 [j] * v2 [k];
+                    }
+                }
+//                sink_c_matrix<T, N, N> () (m);
+                BOOST_UBLAS_NOT_USED(m);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_my_outer_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m (N, N);
+            ublas::matrix_range<M> mr (m, ublas::range (0, N), ublas::range (0, N));
+            static V v1 (N), v2 (N);
+            ublas::vector_range<V> vr1 (v1, ublas::range (0, N)),
+                                   vr2 (v2, ublas::range (0, N));
+            initialize_vector (vr1);
+            initialize_vector (vr2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                mr = - ublas::outer_prod (vr1, vr2);
+//                sink_matrix (mr);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m (N, N);
+            ublas::matrix_range<M> mr (m, ublas::range (0, N), ublas::range (0, N));
+            static V v1 (N), v2 (N);
+            ublas::vector_range<V> vr1 (v1, ublas::range (0, N)),
+                                   vr2 (v2, ublas::range (0, N));
+            initialize_vector (vr1);
+            initialize_vector (vr2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                mr.assign (- ublas::outer_prod (vr1, vr2));
+//                sink_matrix (mr);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_cpp_outer_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m (N * N);
+            static V v1 (N), v2 (N);
+            initialize_vector (v1);
+            initialize_vector (v2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m [N * j + k] = - v1 [j] * v2 [k];
+                    }
+                }
+//                sink_vector (m);
+            }
+            footer<value_type> () (N * N, N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T, int N>
+struct bench_c_matrix_vector_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m;
+            static typename c_vector_traits<T, N>::type v1, v2;
+            initialize_c_matrix<T, N, N> () (m);
+            initialize_c_vector<T, N> () (v1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    v2 [j] = 0;
+                    for (int k = 0; k < N; ++ k) {
+                        v2 [j] += m [j] [k] * v1 [k];
+                    }
+                }
+//                sink_c_vector<T, N> () (v2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_my_matrix_vector_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m (N, N);
+            ublas::matrix_range<M> mr (m, ublas::range (0, N), ublas::range (0, N));
+            static V v1 (N), v2 (N);
+            ublas::vector_range<V> vr1 (v1, ublas::range (0, N)),
+                                   vr2 (v2, ublas::range (0, N));
+            initialize_matrix (mr);
+            initialize_vector (vr1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                vr2 = ublas::prod (mr, vr1);
+//                sink_vector (vr2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m (N, N);
+            ublas::matrix_range<M> mr (m, ublas::range (0, N), ublas::range (0, N));
+            static V v1 (N), v2 (N);
+            ublas::vector_range<V> vr1 (v1, ublas::range (0, N)),
+                                   vr2 (v2, ublas::range (0, N));
+            initialize_matrix (mr);
+            initialize_vector (vr1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                vr2.assign (ublas::prod (mr, vr1));
+//                sink_vector (vr2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, class V, int N>
+struct bench_cpp_matrix_vector_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m (N * N);
+            static V v1 (N), v2 (N);
+            initialize_vector (m);
+            initialize_vector (v1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    std::valarray<value_type> row (m [std::slice (N * j, N, 1)]);
+                    v2 [j] = (row * v1).sum ();
+                }
+//                sink_vector (v2);
+            }
+            footer<value_type> () (N * N, N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T, int N>
+struct bench_c_matrix_add {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m1, m2, m3;
+            initialize_c_matrix<T, N, N> () (m1);
+            initialize_c_matrix<T, N, N> () (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m3 [j] [k] = - (m1 [j] [k] + m2 [j] [k]);
+                    }
+                }
+//                sink_c_matrix<T, N, N> () (m3);
+                BOOST_UBLAS_NOT_USED(m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_my_matrix_add {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m1 (N, N), m2 (N, N), m3 (N, N);
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3 = - (m1 + m2);
+//                sink_matrix (m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m1 (N, N), m2 (N, N), m3 (N, N);
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3.assign (- (m1 + m2));
+//                sink_matrix (m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_cpp_matrix_add {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m1 (N * N), m2 (N * N), m3 (N * N);
+            initialize_vector (m1);
+            initialize_vector (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                m3 = - (m1 + m2);
+//                sink_vector (m3);
+            }
+            footer<value_type> () (0, 2 * N * N, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+// Benchmark O (n ^ 2)
+template<class T, int N>
+void bench_2<T, N>::operator () (int runs) {
+    header ("bench_2");
+
+    header ("outer_prod");
+
+    header ("C array");
+    bench_c_outer_prod<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_matrix, c_vector safe");
+    bench_my_outer_prod<ublas::c_matrix<T, N, N>,
+                        ublas::c_vector<T, N>, N> () (runs, safe_tag ());
+
+    header ("c_matrix, c_vector fast");
+    bench_my_outer_prod<ublas::c_matrix<T, N, N>,
+                        ublas::c_vector<T, N>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("matrix<bounded_array>, vector<bounded_array> safe");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >,
+                        ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, safe_tag ());
+
+    header ("matrix<bounded_array>, vector<bounded_array> fast");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >,
+                        ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("matrix<unbounded_array>, vector<unbounded_array> safe");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >,
+                        ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<unbounded_array>, vector<unbounded_array> fast");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >,
+                        ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("matrix<std::valarray>, vector<std::valarray> safe");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >,
+                        ublas::vector<T, std::valarray<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::valarray>, vector<std::valarray> fast");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >,
+                        ublas::vector<T, std::valarray<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("matrix<std::vector>, vector<std::vector> safe");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >,
+                        ublas::vector<T, std::vector<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::vector>, vector<std::vector> fast");
+    bench_my_outer_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >,
+                        ublas::vector<T, std::vector<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_outer_prod<std::valarray<T>, std::valarray<T>, N> () (runs);
+#endif
+
+    header ("prod (matrix, vector)");
+
+    header ("C array");
+    bench_c_matrix_vector_prod<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_matrix, c_vector safe");
+    bench_my_matrix_vector_prod<ublas::c_matrix<T, N, N>,
+                                ublas::c_vector<T, N>, N> () (runs, safe_tag ());
+
+    header ("c_matrix, c_vector fast");
+    bench_my_matrix_vector_prod<ublas::c_matrix<T, N, N>,
+                                ublas::c_vector<T, N>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("matrix<bounded_array>, vector<bounded_array> safe");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >,
+                                ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, safe_tag ());
+
+    header ("matrix<bounded_array>, vector<bounded_array> fast");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >,
+                                ublas::vector<T, ublas::bounded_array<T, N> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("matrix<unbounded_array>, vector<unbounded_array> safe");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >,
+                                ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<unbounded_array>, vector<unbounded_array> fast");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >,
+                                ublas::vector<T, ublas::unbounded_array<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("matrix<std::valarray>, vector<std::valarray> safe");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >,
+                                ublas::vector<T, std::valarray<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::valarray>, vector<std::valarray> fast");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >,
+                                ublas::vector<T, std::valarray<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("matrix<std::vector>, vector<std::vector> safe");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >,
+                                ublas::vector<T, std::vector<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::vector>, vector<std::vector> fast");
+    bench_my_matrix_vector_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >,
+                                ublas::vector<T, std::vector<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_matrix_vector_prod<std::valarray<T>, std::valarray<T>, N> () (runs);
+#endif
+
+    header ("matrix + matrix");
+
+    header ("C array");
+    bench_c_matrix_add<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_matrix safe");
+    bench_my_matrix_add<ublas::c_matrix<T, N, N>, N> () (runs, safe_tag ());
+
+    header ("c_matrix fast");
+    bench_my_matrix_add<ublas::c_matrix<T, N, N>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("matrix<bounded_array> safe");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, N> () (runs, safe_tag ());
+
+    header ("matrix<bounded_array> fast");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("matrix<unbounded_array> safe");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<unbounded_array> fast");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("matrix<std::valarray> safe");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::valarray<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::valarray> fast");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::valarray<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("matrix<std::vector> safe");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::vector<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::vector> fast");
+    bench_my_matrix_add<ublas::matrix<T, ublas::row_major, std::vector<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_matrix_add<std::valarray<T>, N> () (runs);
+#endif
+}
+
+#ifdef USE_FLOAT
+template struct bench_2<float, 3>;
+template struct bench_2<float, 10>;
+template struct bench_2<float, 30>;
+template struct bench_2<float, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_2<double, 3>;
+template struct bench_2<double, 10>;
+template struct bench_2<double, 30>;
+template struct bench_2<double, 100>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_2<std::complex<float>, 3>;
+template struct bench_2<std::complex<float>, 10>;
+template struct bench_2<std::complex<float>, 30>;
+template struct bench_2<std::complex<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_2<std::complex<double>, 3>;
+template struct bench_2<std::complex<double>, 10>;
+template struct bench_2<std::complex<double>, 30>;
+template struct bench_2<std::complex<double>, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench3/bench33.cpp b/benchmarks/bench3/bench33.cpp
new file mode 100644
index 0000000..9b8e107
--- /dev/null
+++ b/benchmarks/bench3/bench33.cpp
@@ -0,0 +1,198 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "bench3.hpp"
+
+template<class T, int N>
+struct bench_c_matrix_prod {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static typename c_matrix_traits<T, N, N>::type m1, m2, m3;
+            initialize_c_matrix<T, N, N> () (m1);
+            initialize_c_matrix<T, N, N> () (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    for (int k = 0; k < N; ++ k) {
+                        m3 [j] [k] = 0;
+                        for (int l = 0; l < N; ++ l) {
+                            m3 [j] [k] += m1 [j] [l] * m2 [l] [k];
+                        }
+                    }
+                }
+//                sink_c_matrix<T, N, N> () (m3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_my_matrix_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs, safe_tag) const {
+        try {
+            static M m1 (N, N), m2 (N, N), m3 (N, N);
+            ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                   mr2 (m2, ublas::range (0, N), ublas::range (0, N)),
+                                   mr3 (m3, ublas::range (0, N), ublas::range (0, N));
+            initialize_matrix (mr1);
+            initialize_matrix (mr2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                mr3 = ublas::prod (mr1, mr2);
+//                sink_matrix (mr3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+    void operator () (int runs, fast_tag) const {
+        try {
+            static M m1 (N, N), m2 (N, N), m3 (N, N);
+            ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                   mr2 (m2, ublas::range (0, N), ublas::range (0, N)),
+                                   mr3 (m3, ublas::range (0, N), ublas::range (0, N));
+            initialize_matrix (mr1);
+            initialize_matrix (mr2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                mr3.assign (ublas::prod (mr1, mr2));
+//                sink_matrix (mr3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class M, int N>
+struct bench_cpp_matrix_prod {
+    typedef typename M::value_type value_type;
+
+    void operator () (int runs) const {
+        try {
+            static M m1 (N * N), m2 (N * N), m3 (N * N);
+            initialize_vector (m1);
+            initialize_vector (m2);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                for (int j = 0; j < N; ++ j) {
+                    std::valarray<value_type> row (m1 [std::slice (N * j, N, 1)]);
+                    for (int k = 0; k < N; ++ k) {
+                        std::valarray<value_type> column (m2 [std::slice (k, N, N)]);
+                        m3 [N * j + k] = (row * column).sum ();
+                    }
+                }
+//                sink_vector (m3);
+            }
+            footer<value_type> () (N * N * N, N * N * (N - 1), runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+// Benchmark O (n ^ 3)
+template<class T, int N>
+void bench_3<T, N>::operator () (int runs) {
+    header ("bench_3");
+
+    header ("prod (matrix, matrix)");
+
+    header ("C array");
+    bench_c_matrix_prod<T, N> () (runs);
+
+#ifdef USE_C_ARRAY
+    header ("c_matrix safe");
+    bench_my_matrix_prod<ublas::c_matrix<T, N, N>, N> () (runs, safe_tag ());
+
+    header ("c_matrix fast");
+    bench_my_matrix_prod<ublas::c_matrix<T, N, N>, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_BOUNDED_ARRAY
+    header ("matrix<bounded_array> safe");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, N> () (runs, safe_tag ());
+
+    header ("matrix<bounded_array> fast");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, ublas::bounded_array<T, N * N> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+    header ("matrix<unbounded_array> safe");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<unbounded_array> fast");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, ublas::unbounded_array<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("matrix<std::valarray> safe");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::valarray> fast");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, std::valarray<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VECTOR
+    header ("matrix<std::vector> safe");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >, N> () (runs, safe_tag ());
+
+    header ("matrix<std::vector> fast");
+    bench_my_matrix_prod<ublas::matrix<T, ublas::row_major, std::vector<T> >, N> () (runs, fast_tag ());
+#endif
+
+#ifdef USE_STD_VALARRAY
+    header ("std::valarray");
+    bench_cpp_matrix_prod<std::valarray<T>, N> () (runs);
+#endif
+}
+
+#ifdef USE_FLOAT
+template struct bench_3<float, 3>;
+template struct bench_3<float, 10>;
+template struct bench_3<float, 30>;
+template struct bench_3<float, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_3<double, 3>;
+template struct bench_3<double, 10>;
+template struct bench_3<double, 30>;
+template struct bench_3<double, 100>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_3<std::complex<float>, 3>;
+template struct bench_3<std::complex<float>, 10>;
+template struct bench_3<std::complex<float>, 30>;
+template struct bench_3<std::complex<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_3<std::complex<double>, 3>;
+template struct bench_3<std::complex<double>, 10>;
+template struct bench_3<std::complex<double>, 30>;
+template struct bench_3<std::complex<double>, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench4/Jamfile.v2 b/benchmarks/bench4/Jamfile.v2
new file mode 100644
index 0000000..94a9f07
--- /dev/null
+++ b/benchmarks/bench4/Jamfile.v2
@@ -0,0 +1,12 @@
+# Copyright (c) 2004 Michael Stevens
+# Use, modification and distribution are subject to the
+# Boost Software License, Version 1.0. (See accompanying file
+# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# bench4 measurs the abstraction penalty of dense matrix and vector
+#        operations with boost::numeric::interval(s).
+
+exe bench4
+    : bench4.cpp bench41.cpp bench42.cpp bench43.cpp
+    : <define>BOOST_UBLAS_USE_INTERVAL
+    ;
diff --git a/benchmarks/bench4/bench4.cpp b/benchmarks/bench4/bench4.cpp
new file mode 100644
index 0000000..6d460eb
--- /dev/null
+++ b/benchmarks/bench4/bench4.cpp
@@ -0,0 +1,135 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/interval.hpp>
+#include <boost/numeric/interval/io.hpp>
+#include "../bench1/bench1.hpp"
+
+void header (std::string text) {
+    std::cout << text << std::endl;
+}
+
+template<class T>
+struct peak_c_plus {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static T s (0);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                s += T (0);
+//                sink_scalar (s);
+            }
+            footer<value_type> () (0, 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+template<class T>
+struct peak_c_multiplies {
+    typedef T value_type;
+
+    void operator () (int runs) const {
+        try {
+            static T s (1);
+            boost::timer t;
+            for (int i = 0; i < runs; ++ i) {
+                s *= T (1);
+//                sink_scalar (s);
+            }
+            footer<value_type> () (0, 1, runs, t.elapsed ());
+        }
+        catch (std::exception &e) {
+            std::cout << e.what () << std::endl;
+        }
+    }
+};
+
+template<class T>
+void peak<T>::operator () (int runs) {
+    header ("peak");
+
+    header ("plus");
+    peak_c_plus<T> () (runs);
+
+    header ("multiplies");
+    peak_c_multiplies<T> () (runs);
+}
+
+template struct peak<boost::numeric::interval<float> >;
+template struct peak<boost::numeric::interval<double> >;
+
+#ifdef USE_BOOST_COMPLEX
+
+template struct peak<boost::complex<boost::numeric::interval<float> > >;
+template struct peak<boost::complex<boost::numeric::interval<double> > >;
+
+#endif
+
+
+
+template <typename scalar> 
+void do_bench (std::string type_string, int scale)
+{
+    header (type_string);
+    peak<scalar> () (1000000 * scale);
+
+    header (type_string + ", 3");
+    bench_1<scalar, 3> () (1000000 * scale);
+    bench_2<scalar, 3> () (300000 * scale);
+    bench_3<scalar, 3> () (100000 * scale);
+
+    header (type_string + ", 10");
+    bench_1<scalar, 10> () (300000 * scale);
+    bench_2<scalar, 10> () (30000 * scale);
+    bench_3<scalar, 10> () (3000 * scale);
+
+    header (type_string + ", 30");
+    bench_1<scalar, 30> () (100000 * scale);
+    bench_2<scalar, 30> () (3000 * scale);
+    bench_3<scalar, 30> () (100 * scale);
+
+    header (type_string + ", 100");
+    bench_1<scalar, 100> () (30000 * scale);
+    bench_2<scalar, 100> () (300 * scale);
+    bench_3<scalar, 100> () (3 * scale);
+}
+
+int main (int argc, char *argv []) {
+
+    int scale = 1;
+    if (argc > 1)
+        scale = std::atoi (argv [1]);
+
+#ifdef USE_FLOAT
+    do_bench<boost::numeric::interval<float> > ("boost::numeric::interval<FLOAT>", scale);
+#endif
+
+#ifdef USE_DOUBLE
+    do_bench<boost::numeric::interval<double> > ("boost::numeric::interval<DOUBLE>", scale);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    do_bench<std::complex<boost::numeric::interval<float> > > ("boost::numeric::interval<COMPLEX<FLOAT>>", scale);
+#endif
+
+#ifdef USE_DOUBLE
+    do_bench<std::complex<doublboost::numeric::interval<double> > > ("boost::numeric::interval<COMPLEX<DOUBLE>>", scale);
+#endif
+#endif
+
+    return 0;
+}
diff --git a/benchmarks/bench4/bench41.cpp b/benchmarks/bench4/bench41.cpp
new file mode 100644
index 0000000..2ef2d69
--- /dev/null
+++ b/benchmarks/bench4/bench41.cpp
@@ -0,0 +1,46 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/interval.hpp>
+#include <boost/numeric/interval/io.hpp>
+#include "../bench1/bench11.cpp"
+
+
+#ifdef USE_FLOAT
+template struct bench_1<boost::numeric::interval<float>, 3>;
+template struct bench_1<boost::numeric::interval<float>, 10>;
+template struct bench_1<boost::numeric::interval<float>, 30>;
+template struct bench_1<boost::numeric::interval<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_1<boost::numeric::interval<double>, 3>;
+template struct bench_1<boost::numeric::interval<double>, 10>;
+template struct bench_1<boost::numeric::interval<double>, 30>;
+template struct bench_1<boost::numeric::interval<double>, 100>;
+#endif
+
+#ifdef USE_BOOST_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_1<boost::complex<boost::numeric::interval<float> >, 3>;
+template struct bench_1<boost::complex<boost::numeric::interval<float> >, 10>;
+template struct bench_1<boost::complex<boost::numeric::interval<float> >, 30>;
+template struct bench_1<boost::complex<boost::numeric::interval<float> >, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_1<boost::complex<boost::numeric::interval<double> >, 3>;
+template struct bench_1<boost::complex<boost::numeric::interval<double> >, 10>;
+template struct bench_1<boost::complex<boost::numeric::interval<double> >, 30>;
+template struct bench_1<boost::complex<boost::numeric::interval<double> >, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench4/bench42.cpp b/benchmarks/bench4/bench42.cpp
new file mode 100644
index 0000000..55f9060
--- /dev/null
+++ b/benchmarks/bench4/bench42.cpp
@@ -0,0 +1,46 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/interval.hpp>
+#include <boost/numeric/interval/io.hpp>
+#include "../bench1/bench12.cpp"
+
+
+#ifdef USE_FLOAT
+template struct bench_2<boost::numeric::interval<float>, 3>;
+template struct bench_2<boost::numeric::interval<float>, 10>;
+template struct bench_2<boost::numeric::interval<float>, 30>;
+template struct bench_2<boost::numeric::interval<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_2<boost::numeric::interval<double>, 3>;
+template struct bench_2<boost::numeric::interval<double>, 10>;
+template struct bench_2<boost::numeric::interval<double>, 30>;
+template struct bench_2<boost::numeric::interval<double>, 100>;
+#endif
+
+#ifdef USE_BOOST_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_2<boost::complex<boost::numeric::interval<float> >, 3>;
+template struct bench_2<boost::complex<boost::numeric::interval<float> >, 10>;
+template struct bench_2<boost::complex<boost::numeric::interval<float> >, 30>;
+template struct bench_2<boost::complex<boost::numeric::interval<float> >, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_2<boost::complex<boost::numeric::interval<double> >, 3>;
+template struct bench_2<boost::complex<boost::numeric::interval<double> >, 10>;
+template struct bench_2<boost::complex<boost::numeric::interval<double> >, 30>;
+template struct bench_2<boost::complex<boost::numeric::interval<double> >, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench4/bench43.cpp b/benchmarks/bench4/bench43.cpp
new file mode 100644
index 0000000..c39655a
--- /dev/null
+++ b/benchmarks/bench4/bench43.cpp
@@ -0,0 +1,46 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/interval.hpp>
+#include <boost/numeric/interval/io.hpp>
+#include "../bench1/bench13.cpp"
+
+
+#ifdef USE_FLOAT
+template struct bench_3<boost::numeric::interval<float>, 3>;
+template struct bench_3<boost::numeric::interval<float>, 10>;
+template struct bench_3<boost::numeric::interval<float>, 30>;
+template struct bench_3<boost::numeric::interval<float>, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_3<boost::numeric::interval<double>, 3>;
+template struct bench_3<boost::numeric::interval<double>, 10>;
+template struct bench_3<boost::numeric::interval<double>, 30>;
+template struct bench_3<boost::numeric::interval<double>, 100>;
+#endif
+
+#ifdef USE_BOOST_COMPLEX
+#ifdef USE_FLOAT
+template struct bench_3<boost::complex<boost::numeric::interval<float> >, 3>;
+template struct bench_3<boost::complex<boost::numeric::interval<float> >, 10>;
+template struct bench_3<boost::complex<boost::numeric::interval<float> >, 30>;
+template struct bench_3<boost::complex<boost::numeric::interval<float> >, 100>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct bench_3<boost::complex<boost::numeric::interval<double> >, 3>;
+template struct bench_3<boost::complex<boost::numeric::interval<double> >, 10>;
+template struct bench_3<boost::complex<boost::numeric::interval<double> >, 30>;
+template struct bench_3<boost::complex<boost::numeric::interval<double> >, 100>;
+#endif
+#endif
diff --git a/benchmarks/bench5/Jamfile.v2 b/benchmarks/bench5/Jamfile.v2
new file mode 100644
index 0000000..d180f5c
--- /dev/null
+++ b/benchmarks/bench5/Jamfile.v2
@@ -0,0 +1,11 @@
+# Copyright (c) 2004-2010 Michael Stevens, David Bellot
+# Use, modification and distribution are subject to the
+# Boost Software License, Version 1.0. (See accompanying file
+# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# bench5 measures performance of the assignment operator
+
+exe bench5
+    : assignment_bench.cpp
+    : <define>BOOST_UBLAS_USE_INTERVAL
+    ;
diff --git a/benchmarks/bench5/assignment_bench.cpp b/benchmarks/bench5/assignment_bench.cpp
new file mode 100644
index 0000000..532f379
--- /dev/null
+++ b/benchmarks/bench5/assignment_bench.cpp
@@ -0,0 +1,141 @@
+//
+//  Copyright (c) 2010 Athanasios Iliopoulos
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/numeric/ublas/assignment.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/timer.hpp>
+
+using namespace boost::numeric::ublas;
+
+int main() {
+
+    boost::timer timer;
+
+    unsigned int iterations = 1000000000;
+    double elapsed_exp, elapsed_assigner;
+
+    std::cout << "Ublas vector<double> Benchmarks------------------------ " << "\n";
+
+    {
+    std::cout << "Size 2 vector: " << "\n";
+    vector<double> a(2);
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++) {
+        a(0)=0; a(1)=1;
+    }
+    elapsed_exp = timer.elapsed();
+    std::cout << "Explicit element assign time: " << elapsed_exp << " secs" << "\n";
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++)
+        a <<= 0, 1;
+    elapsed_assigner = timer.elapsed();
+    std::cout << "Assigner time: " << elapsed_assigner << " secs" << "\n";
+    std::cout << "Difference: " << (elapsed_assigner/elapsed_exp-1)*100 << "%" << std::endl;
+    }
+
+    {
+    std::cout << "Size 3 vector: " << "\n";
+    vector<double> a(3);
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++) {
+        a(0)=0; a(1)=1; a(2)=2;
+    }
+    elapsed_exp = timer.elapsed();
+    std::cout << "Explicit element assign time: " << elapsed_exp << " secs" << "\n";
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++)
+        a <<= 0, 1, 2;
+    elapsed_assigner = timer.elapsed();
+    std::cout << "Assigner time: " << elapsed_assigner << " secs" << "\n";
+    std::cout << "Difference: " << (elapsed_assigner/elapsed_exp-1)*100 << "%" << std::endl;
+    }
+
+    iterations = 100000000;
+
+    {
+    std::cout << "Size 8 vector: " << "\n";
+    vector<double> a(8);
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++) {
+        a(0)=0; a(1)=1; a(2)=2; a(3)=3; a(4)=4; a(5)=5; a(6)=6; a(7)=7;
+    }
+    elapsed_exp = timer.elapsed();
+    std::cout << "Explicit element assign time: " << elapsed_exp << " secs" << "\n";
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++)
+        a <<= 0, 1, 2, 3, 4, 5, 6, 7;
+    elapsed_assigner = timer.elapsed();
+    std::cout << "Assigner time: " << elapsed_assigner << " secs" << "\n";
+    std::cout << "Difference: " << (elapsed_assigner/elapsed_exp-1)*100 << "%" << std::endl;
+    }
+
+
+    std::cout << "Ublas matrix<double> Benchmarks------------------------ " << "\n";
+
+    iterations = 200000000;
+    {
+    std::cout << "Size 3x3 matrix: " << "\n";
+    matrix<double> a(3,3);
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++) {
+        a(0,0)=0; a(0,1)=1; a(0,2)=2;
+        a(1,0)=3; a(1,1)=4; a(1,2)=5;
+        a(2,0)=6; a(2,1)=7; a(2,2)=8;
+    }
+    elapsed_exp = timer.elapsed();
+    std::cout << "Explicit element assign time: " << elapsed_exp << " secs" << "\n";
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++)
+        a <<= 0, 1, 2, 3, 4, 5, 6, 7, 8;
+    elapsed_assigner = timer.elapsed();
+    std::cout << "Assigner time: " << elapsed_assigner << " secs" << "\n";
+    std::cout << "Difference: " << (elapsed_assigner/elapsed_exp-1)*100 << "%" << std::endl;
+    }
+
+    std::cout << "Size 2x2 matrix: " << "\n";
+    iterations = 500000000;
+    {
+    matrix<double> a(2,2);
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++) {
+        a(0,0)=0; a(0,1)=1;
+        a(1,0)=3; a(1,1)=4;
+    }
+    elapsed_exp = timer.elapsed();
+    std::cout << "Explicit element assign time: " << elapsed_exp << " secs" << "\n";
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++)
+        a <<= 0, 1, 3, 4;
+    elapsed_assigner = timer.elapsed();
+    std::cout << "Assigner time: " << elapsed_assigner << " secs" << "\n";
+
+    std::cout << "Difference: " << (elapsed_assigner/elapsed_exp-1)*100 << "%" << std::endl;
+
+    timer.restart();
+    for(unsigned int i=0; i!=iterations; i++)
+        a <<= traverse_policy::by_row_no_wrap(), 0, 1, next_row(), 3, 4;
+    elapsed_assigner = timer.elapsed();
+    std::cout << "Assigner time no_wrap: " << elapsed_assigner << " secs" << "\n";
+    std::cout << "Difference: " << (elapsed_assigner/elapsed_exp-1)*100 << "%" << std::endl;
+    }
+
+    return 0;
+}
+
diff --git a/doc/banded.html b/doc/banded.html
new file mode 100644
index 0000000..6ce82f2
--- /dev/null
+++ b/doc/banded.html
@@ -0,0 +1,580 @@
+<!DOCTYPE html PUBLIC "-//W3C/utf-8XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Banded Matrix</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Banded Matrix</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="banded_matrix"></a>Banded Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>banded_matrix&lt;T, F, A&gt;</code> is
+the base container adaptor for banded matrices. For a <em>(m x
+n</em>)-dimensional banded matrix with <em>l</em> lower and
+<em>u</em> upper diagonals and <em>0 &lt;= i &lt; m</em>, <em>0
+&lt;= j &lt; n</em> holds <em>b</em><sub><em>i, j</em></sub> <em>=
+0</em>, if <em>i &gt; j + l</em> or <em>i &lt; j - u</em>. The
+storage of banded matrices is packed.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/banded.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    banded_matrix&lt;double&gt; m (3, 3, 1, 1);
+    for (signed i = 0; i &lt; signed (m.size1 ()); ++ i)
+        for (signed j = std::max (i - 1, 0); j &lt; std::min (i + 2, signed (m.size2 ())); ++ j)
+            m (i, j) = 3 * i + j;
+    std::cout &lt;&lt; m &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header banded.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>Functor describing the storage organization. <a href=
+"#banded_matrix_1">[1]</a></td>
+<td><code>row_major</code></td>
+</tr>
+<tr>
+<td><code>A</code></td>
+<td>The type of the adapted array. <a href=
+"#banded_matrix_2">[2]</a></td>
+<td><code>unbounded_array&lt;T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;banded_matrix&lt;T, F, A&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>banded_matrix ()</code></td>
+<td>Allocates an uninitialized <code>banded_matrix</code> that
+holds zero rows of zero elements.</td>
+</tr>
+<tr>
+<td><code>banded_matrix (size_type size1, size_type size2,
+size_type lower = 0, size_type upper = 0)</code></td>
+<td>Allocates an uninitialized <code>banded_matrix</code> that
+holds <code>(lower + 1 + upper)</code> diagonals around the main
+diagonal of a matrix with <code>size1</code> rows of
+<code>size2</code> elements.</td>
+</tr>
+<tr>
+<td><code>banded_matrix (const banded_matrix &amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_matrix (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size1, size_type size2, size_type
+lower = 0, size_type upper = 0, bool preserve = true)</code></td>
+<td>Reallocates a <code>banded_matrix</code> to hold <code>(lower +
+1 + upper)</code> diagonals around the main diagonal of a matrix
+with <code>size1</code> rows of <code>size2</code> elements. The
+existing elements of the <code>banded_matrix</code> are preseved
+when specified.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>size_type lower () const</code></td>
+<td>Returns the number of diagonals below the main diagonal.</td>
+</tr>
+<tr>
+<td><code>size_type upper () const</code></td>
+<td>Returns the number of diagonals above the main diagonal.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns a <code>const</code> reference of the <code>j</code>
+-th element in the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>banded_matrix &amp;operator = (const banded_matrix
+&amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>banded_matrix &amp;assign_temporary (banded_matrix
+&amp;m)</code></td>
+<td>Assigns a temporary. May change the banded matrix
+<code>m</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_matrix &amp;operator = (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_matrix &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the banded matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_matrix &amp;operator += (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the banded matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_matrix &amp;plus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a matrix expression to the banded matrix. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_matrix &amp;operator -= (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the banded matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_matrix &amp;minus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a matrix expression from the banded matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+banded_matrix &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the banded matrix
+with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+banded_matrix &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the banded matrix
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (banded_matrix &amp;m)</code></td>
+<td>Swaps the contents of the banded matrices.</td>
+</tr>
+<tr>
+<td><code>void insert (size_type i, size_type j, const_reference
+t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>j</code>-th
+element of the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void erase (size_type i, size_type j)</code></td>
+<td>Erases the value at the <code>j</code>-th elemenst of the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the matrix.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>banded_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>banded_matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="banded_matrix_1" id="banded_matrix_1">[1]</a> Supported
+parameters for the storage organization are <code>row_major</code>
+and <code>column_major</code>.</p>
+<p><a name="banded_matrix_2" id="banded_matrix_2">[2]</a> Supported
+parameters for the adapted array are
+<code>unbounded_array&lt;T&gt;</code> ,
+<code>bounded_array&lt;T&gt;</code> and
+<code>std::vector&lt;T&gt;</code> .</p>
+<h2><a name="banded_adaptor"></a>Banded Adaptor</h2>
+<h4>Description</h4>
+<p>The templated class <code>banded_adaptor&lt;M&gt;</code> is a
+banded matrix adaptor for other matrices.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/banded.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    banded_adaptor&lt;matrix&lt;double&gt; &gt; ba (m, 1, 1);
+    for (signed i = 0; i &lt; signed (ba.size1 ()); ++ i)
+        for (signed j = std::max (i - 1, 0); j &lt; std::min (i + 2, signed (ba.size2 ())); ++ j)
+            ba (i, j) = 3 * i + j;
+    std::cout &lt;&lt; ba &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header banded.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>M</code></td>
+<td>The type of the adapted matrix.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;banded_adaptor&lt;M&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>banded_adaptor (matrix_type &amp;data, size_type lower =
+0, size_type upper = 0)</code></td>
+<td>Constructs a <code>banded_adaptor</code> that holds
+<code>(lower + 1 + upper)</code> diagonals around the main diagonal
+of a matrix.</td>
+</tr>
+<tr>
+<td><code>banded_adaptor (const banded_adaptor &amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_adaptor (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>size_type lower () const</code></td>
+<td>Returns the number of diagonals below the main diagonal.</td>
+</tr>
+<tr>
+<td><code>size_type upper () const</code></td>
+<td>Returns the number of diagonals above the main diagonal.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns a <code>const</code> reference of the <code>j</code>
+-th element in the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>banded_adaptor &amp;operator = (const banded_adaptor
+&amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>banded_adaptor &amp;assign_temporary (banded_adaptor
+&amp;m)</code></td>
+<td>Assigns a temporary. May change the banded adaptor
+<code>m</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_adaptor &amp;operator = (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_adaptor &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the banded adaptor. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_adaptor &amp;operator += (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the banded adaptor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_adaptor &amp;plus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a matrix expression to the banded adaptor. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_adaptor &amp;operator -= (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the banded adaptor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+banded_adaptor &amp;minus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a matrix expression from the banded adaptor. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+banded_adaptor &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the banded adaptor
+with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+banded_adaptor &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the banded adaptor
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (banded_adaptor &amp;m)</code></td>
+<td>Swaps the contents of the banded adaptors.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>banded_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>banded_adaptor</code>.</td>
+</tr>
+</tbody>
+</table>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt</a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/blas.html b/doc/blas.html
new file mode 100644
index 0000000..07573e8
--- /dev/null
+++ b/doc/blas.html
@@ -0,0 +1,452 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>BLAS</title>
+  <meta name="GENERATOR" content="Quanta Plus" />
+  <meta name="AUTHOR" content="Gunter Winkler" />
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+  <link rel="stylesheet" href="ublas.css" type="text/css" />
+  <script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+  <script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+</head>
+<body>
+
+
+<h1>Level 3 BLAS</h1>
+<div class="toc" id="toc"></div>
+<hr />
+<a name="_details"></a>
+
+<table summary="" border=0 cellpadding=0 cellspacing=0>
+<tr><td></td></tr>
+<tr><td colspan=2><br /><h2>Functions</h2></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>template&lt;class M1, class T, class M2, class M3&gt; M1 &amp;&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="#ga0">boost::numeric::ublas::blas_3::tmm</a> (M1 &amp;m1, const T &amp;t, const M2 &amp;m2, const M3 &amp;m3)</td></tr>
+
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">triangular matrix multiplication  <a href="#ga0"></a><br /><br /></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>template&lt;class M1, class T, class M2, class C&gt; M1 &amp;&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="#ga1">boost::numeric::ublas::blas_3::tsm</a> (M1 &amp;m1, const T &amp;t, const M2 &amp;m2, C)</td></tr>
+
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">triangular solve <em>m2</em> * <em>x</em> = <em>t</em> * <em>m1</em> in place, <em>m2</em> is a triangular matrix  <a href="#ga1"></a><br /><br /></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>template&lt;class M1, class T1, class T2, class M2, class M3&gt; M1 &amp;&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="#ga2">boost::numeric::ublas::blas_3::gmm</a> (M1 &amp;m1, const T1 &amp;t1, const T2 &amp;t2, const M2 &amp;m2, const M3 &amp;m3)</td></tr>
+
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">general matrix multiplication  <a href="#ga2"></a><br /><br /></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>template&lt;class M1, class T1, class T2, class M2&gt; M1 &amp;&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="#ga3">boost::numeric::ublas::blas_3::srk</a> (M1 &amp;m1, const T1 &amp;t1, const T2 &amp;t2, const M2 &amp;m2)</td></tr>
+
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">symmetric rank k update: <em>m1</em> = <em>t</em> * <em>m1</em> + <em>t2</em> * (<em>m2</em> * <em>m2<sup>T</sup></em>)  <a href="#ga3"></a><br /><br /></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>template&lt;class M1, class T1, class T2, class M2&gt; M1 &amp;&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="#ga4">boost::numeric::ublas::blas_3::hrk</a> (M1 &amp;m1, const T1 &amp;t1, const T2 &amp;t2, const M2 &amp;m2)</td></tr>
+
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">hermitian rank k update: <em>m1</em> = <em>t</em> * <em>m1</em> + <em>t2</em> * (<em>m2</em> * <em>m2<sup>H</sup></em>)  <a href="#ga4"></a><br /><br /></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>template&lt;class M1, class T1, class T2, class M2, class M3&gt; M1 &amp;&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="#ga5">boost::numeric::ublas::blas_3::sr2k</a> (M1 &amp;m1, const T1 &amp;t1, const T2 &amp;t2, const M2 &amp;m2, const M3 &amp;m3)</td></tr>
+
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">generalized symmetric rank k update: <em>m1</em> = <em>t1</em> * <em>m1</em> + <em>t2</em> * (<em>m2</em> * <em>m3<sup>T</sup></em>) + <em>t2</em> * (<em>m3</em> * <em>m2<sup>T</sup></em>)  <a href="#ga5"></a><br /><br /></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>template&lt;class M1, class T1, class T2, class M2, class M3&gt; M1 &amp;&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="#ga6">boost::numeric::ublas::blas_3::hr2k</a> (M1 &amp;m1, const T1 &amp;t1, const T2 &amp;t2, const M2 &amp;m2, const M3 &amp;m3)</td></tr>
+
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">generalized hermitian rank k update: <em>m1</em> = <em>t1</em> * <em>m1</em> + <em>t2</em> * (<em>m2</em> * <em>m3<sup>H</sup></em>) + (<em>m3</em> * (<em>t2</em> * <em>m2</em>)<sup>H</sup>)  <a href="#ga6"></a><br /><br /></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>template&lt;class M, class E1, class E2&gt; BOOST_UBLAS_INLINE M &amp;&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="products.html#ga7">boost::numeric::ublas::axpy_prod</a> (const matrix_expression&lt; E1 &gt; &amp;e1, const matrix_expression&lt; E2 &gt; &amp;e2, M &amp;m, bool init=true)</td></tr>
+
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">computes <code>M += A X</code> or <code>M = A X</code> in an optimized fashion.  <a href="products.html#ga7"></a><br /><br /></td></tr>
+<tr><td class="memItemLeft" nowrap align=right valign=top>template&lt;class M, class E1, class E2&gt; BOOST_UBLAS_INLINE M &amp;&nbsp;</td><td class="memItemRight" valign=bottom><a class="el" href="products.html#ga8">boost::numeric::ublas::opb_prod</a> (const matrix_expression&lt; E1 &gt; &amp;e1, const matrix_expression&lt; E2 &gt; &amp;e2, M &amp;m, bool init=true)</td></tr>
+
+<tr><td class="mdescLeft">&nbsp;</td><td class="mdescRight">computes <code>M += A X</code> or <code>M = A X</code> in an optimized fashion.  <a href="products.html#ga8"></a><br /><br /></td></tr>
+</table>
+
+<hr />
+
+<h2>Function Documentation</h2>
+
+<a class="anchor" name="ga0" doxytag="boost::numeric::ublas::blas_3::tmm" ></a>
+<table summary="" class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> M1&amp; tmm           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">M1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M3 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m3</em></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+<p>triangular matrix multiplication </p>
+    </td>
+  </tr>
+</table>
+<a class="anchor" name="ga1" doxytag="boost::numeric::ublas::blas_3::tsm" ></a>
+<table summary="" class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> M1&amp; tsm           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">M1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>C&nbsp;</td>
+          <td class="mdname" nowrap></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+
+<p>
+triangular solve <em>m2</em> * <em>x</em> = <em>t</em> * <em>m1</em> in place, <em>m2</em> is a triangular matrix 
+</p>
+    </td>
+  </tr>
+</table>
+<a class="anchor" name="ga2" doxytag="boost::numeric::ublas::blas_3::gmm" ></a>
+<table summary="" class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> M1&amp; gmm           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">M1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M3 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m3</em></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+
+<p>
+general matrix multiplication 
+</p>
+    </td>
+  </tr>
+</table>
+<a class="anchor" name="ga3" doxytag="boost::numeric::ublas::blas_3::srk" ></a>
+<table summary="" class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> M1&amp; srk           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">M1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m2</em></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+
+<p>
+symmetric rank k update: <em>m1</em> = <em>t</em> * <em>m1</em> + <em>t2</em> * (<em>m2</em> * <em>m2<sup>T</sup></em>) 
+</p>
+<dl compact><dt><b>Todo:</b></dt><dd>use opb_prod() </dd></dl>
+    </td>
+  </tr>
+</table>
+<a class="anchor" name="ga4" doxytag="boost::numeric::ublas::blas_3::hrk" ></a>
+<table summary="" class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> M1&amp; hrk           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">M1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m2</em></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+
+<p>
+hermitian rank k update: <em>m1</em> = <em>t</em> * <em>m1</em> + <em>t2</em> * (<em>m2</em> * <em>m2<sup>H</sup></em>) 
+</p>
+<dl compact><dt><b>Todo:</b></dt><dd>use opb_prod()</dd></dl>
+    </td>
+  </tr>
+</table>
+<a class="anchor" name="ga5" doxytag="boost::numeric::ublas::blas_3::sr2k" ></a>
+<table summary="" class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> M1&amp; sr2k           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">M1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M3 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m3</em></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+
+<p>
+generalized symmetric rank k update: <em>m1</em> = <em>t1</em> * <em>m1</em> + <em>t2</em> * (<em>m2</em> * <em>m3<sup>T</sup></em>) + <em>t2</em> * (<em>m3</em> * <em>m2<sup>T</sup></em>) 
+</p>
+<dl compact><dt><b>Todo:</b></dt><dd>use opb_prod()</dd></dl>
+    </td>
+  </tr>
+</table>
+<a class="anchor" name="ga6" doxytag="boost::numeric::ublas::blas_3::hr2k" ></a>
+<table summary="" class="mdTable" width="100%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> M1&amp; hr2k           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">M1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T1 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const T2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>t2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M2 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const M3 &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m3</em></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+
+<p>
+generalized hermitian rank k update: <em>m1</em> = <em>t1</em> * <em>m1</em> + <em>t2</em> * (<em>m2</em> * <em>m3<sup>H</sup></em>) + (<em>m3</em> * (<em>t2</em> * <em>m2</em>)<sup>H</sup>) 
+</p>
+<dl compact><dt><b>Todo:</b></dt><dd>use opb_prod()</dd></dl>
+    </td>
+  </tr>
+</table>
+
+
+
+<hr />
+<p>Copyright (&copy;) 2000-2004 Michael Stevens, Mathias Koch, 
+Joerg Walter, Gunter Winkler<br />
+Use, modification and distribution are subject to the
+Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt
+or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+http://www.boost.org/LICENSE_1_0.txt</a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/bounded_array.html b/doc/bounded_array.html
new file mode 100644
index 0000000..fea0d7b
--- /dev/null
+++ b/doc/bounded_array.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Bounded Array;</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Bounded Array Storage</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="bounded_array"></a>Bounded Array</h2>
+<h4>Description</h4>
+<p>The templated class <code>bounded_array&lt;T, N, ALLOC&gt;</code> implements a bounded storage array. The bounded array is similar to a C++ array type in that its maximum size is bounded by N and is allocated on the stack instead of the heap. Similarly a <code>bounded_array</code> requires no secondary storage and ALLOC is only used to specify <code>size_type</code> and <code>difference_type</code>.
+</p>
+<p>When resized <code>bounded_array</code> never reallocated the storage. It is therefore always efficient to resize a <code>bounded_array</code> but the size bound N must not be exceeded.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/storage.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    bounded_array&lt;double, 3&gt; a (3);
+    for (unsigned i = 0; i &lt; a.size (); ++ i) {
+        a [i] = i;
+        std::cout &lt;&lt; a [i] &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header storage.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the array.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>N</code></td>
+<td>The allocation size of the array.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>ALLOC</code></td>
+<td>An STL Allocator</td>
+<td>std::allocator</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="storage_concept.html">Storage</a></p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of Storage.</p>
+<h4>Public base classes</h4>
+<p>None.</p>
+<h4>Members</h4>
+<ul>
+<li>The description does not describe what the member actually does, this can be looked up
+in the corresponding concept documentation, but instead contains a remark on the implementation of the
+member inside this model of the concept.</li>
+<li>Typography:
+<ul>
+<li>Members that are not part of the implemented concepts are <font color="blue">in blue</font>.</li>
+</ul>
+</li>
+</ul>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Where defined</th>
+<th>Description</th>
+</tr>
+<tr><td><code>value_type</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td></tr>
+<tr><td><code>pointer</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>value_type*</code></td></tr>
+<tr><td><code>const_pointer</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>const value_type*</code></td></tr>
+<tr><td><code>reference</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>value_type&amp;</code></td></tr>
+<tr><td><code>const_reference</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>const value_type&amp;</code></td></tr>
+<tr><td><code>size_type</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>Alloc::size_type</code></td></tr>
+<tr><td><code>difference_type</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>Alloc::difference_type</code></td></tr>
+<tr><td><code>iterator</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>pointer</code></td></tr>
+<tr><td><code>const_iterator</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>const_pointer</code></td></tr>
+<tr><td><code>revere_iterator</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>std::reverse_iterator&lt;iterator&gt;</code></td></tr>
+<tr><td><code>const_revere_iterator</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>std::reverse_iterator&lt;const_iterator&gt;</code></td></tr>
+<tr>
+<td><code>bounded_array ()</code></td>
+<td><a href="storage_concept.html">Storage</a></td>
+<td>Creates an <code>unbounded_array</code> that holds <strong>zero</strong> elements.</td> 
+</tr>
+<tr>
+<td><code>bounded_array (size_type size)</code></td>
+<td><a href="storage_concept.html">Storage</a></td>
+<td>Creates a uninitialized <code>bounded_array</code> that holds <code>size</code> elements. All the elements are default constructed.</td>
+</tr>
+<tr>
+<td><code>bounded_array (size_type size, const T&amp; init)</code></td>
+<td><a href="storage_concept.html">Storage</a></td>
+<td>Creates an initialized <code>bounded_array</code> that holds <code>size</code> elements. All the elements are constructed from the <code>init</code> value.</td>
+</tr>
+<tr>
+<td><code>bounded_array (const bounded_array &amp;c)</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>~bounded_array ()</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Deallocates the <code>bounded_array</code> itself.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size)</code></td>
+<td><a href="storage_concept.html">Storage</a>
+<td>Reallocates a <code>bounded_array</code> to hold <code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, const T&amp; t)</code></td>
+<td><a href="storage_concept.html">Storage</a>
+<td>Reallocates a <code>bounded_array</code> to hold <code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns the size of the <code>bounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i) const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a <code>const</code> reference of the <code>i</code> -th element.</td>
+</tr>
+<tr>
+<td><code>reference operator [] (size_type i)</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>bounded_array &amp;operator = (const bounded_array &amp;a)</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><font color="blue"><code>bounded_array &amp;assign_temporary (bounded_array &amp;a)</code></font></td>
+<td></td>
+<td>Assigns a temporary. May change the array <code>a</code>.</td>
+</tr>
+<tr>
+<td><code>void swap (bounded_array &amp;a)</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Swaps the contents of the arrays.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning of the <code>bounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of the <code>bounded_array</code>.</td> 
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of the <code>bounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a <code>iterator</code> pointing to the end of the <code>bounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">Reversible Container</a></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the beginning of the reversed <code>bounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">Reversible Container</a></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the end of the reversed <code>bounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td><a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">Reversible Container</a></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the beginning of the reversed <code>bounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td><a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">Reversible Container</a></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of the reversed <code>bounded_array</code>.</td>
+</tr>
+</tbody>
+</table>
+   <hr />
+   <p>
+      Copyright (&copy;) 2000-2004 Michael Stevens, Mathias Koch,
+      Joerg Walter, Gunter Winkler<br />
+      Use, modification and distribution are subject to the
+      Boost Software License, Version 1.0.
+      (See accompanying file LICENSE_1_0.txt
+      or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+         http://www.boost.org/LICENSE_1_0.txt
+      </a>).
+   </p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/container_concept.html b/doc/container_concept.html
new file mode 100644
index 0000000..6c8346f
--- /dev/null
+++ b/doc/container_concept.html
@@ -0,0 +1,424 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Container Concepts</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Container Concepts</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="vector"></a>Vector</h2>
+<h4>Description</h4>
+<p>A Vector describes common aspects of dense, packed and sparse
+vectors.</p>
+<h4>Refinement of</h4>
+<p><a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">DefaultConstructible</a>,
+<a href="expression_concept.html#vector_expression">Vector Expression</a>
+<a href="#vector_expression_note">[1]</a>.</p>
+<h4>Associated types</h4>
+<p>In addition to the types defined by <a href="expression_concept.html#vector_expression">Vector Expression</a></p>
+<table border="1" summary="types">
+<tbody>
+<tr>
+<td>Public base</td>
+<td>vector_container&lt;V&gt;</td>
+<td>V must be derived from this public base type.</td>
+</tr>
+<tr>
+<td>Storage array</td>
+<td>V::array_type</td>
+<td>
+Dense Vector ONLY. The type of underlying storage array used to store the elements. The array_type must model the
+<a href="storage_concept.html"><b>Storage</b></a> concept.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notation</h4>
+<table border="0" summary="notation">
+<tbody>
+<tr>
+<td><code>V</code></td>
+<td>A type that is a model of Vector</td>
+</tr>
+<tr>
+<td><code>v</code></td>
+<td>Objects of type <code>V</code></td>
+</tr>
+<tr>
+<td><code>n, i</code></td>
+<td>Objects of a type convertible to <code>size_type</code></td>
+</tr>
+<tr>
+<td><code>t</code></td>
+<td>Object of a type convertible to <code>value_type</code></td>
+</tr>
+<tr>
+<td><code>p</code></td>
+<td>Object of a type convertible to <code>bool</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Definitions</h4>
+<h4>Valid expressions</h4>
+<p>In addition to the expressions defined in <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">DefaultConstructible</a>,
+<a href="expression_concept.html#vector_expression">Vector Expression</a> the following expressions must be valid.</p>
+<table border="1" summary="expressions">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Type requirements</th>
+<th>Return type</th>
+</tr>
+<tr>
+<td>Sizing constructor</td>
+<td><code>V v (n)</code></td>
+<td>&nbsp;</td>
+<td><code>V</code></td>
+</tr>
+<tr>
+<td>Insert</td>
+<td><code>v.insert_element (i, t)</code></td>
+<td><code>v</code> is mutable.</td>
+<td><code>void</code></td>
+</tr>
+<tr>
+<td>Erase</td>
+<td><code>v.erase_element (i)</code></td>
+<td><code>v</code> is mutable.</td>
+<td><code>void</code></td>
+</tr>
+<tr>
+<td>Clear</td>
+<td><code>v.clear ()</code></td>
+<td><code>v</code> is mutable.</td>
+<td><code>void</code></td>
+</tr>
+<tr>
+<td>Resize</td>
+<td><code>v.resize (n)</code><br />
+<code>v.resize (n, p)</code></td>
+<td><code>v</code> is mutable.</td>
+<td><code>void</code></td>
+</tr>
+<tr>
+<td>Storage</td>
+<td><code>v.data()</code></td>
+<td><code>v</code> is mutable and Dense.</td>
+<td><code>array_type&amp;</code> if <code>v</code> is mutable, <code>const array_type&amp;</code> otherwise</td>
+</tr>
+</tbody>
+</table>
+<h4>Expression semantics</h4>
+<p>Semantics of an expression is defined only where it differs
+from, or is not defined in <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<table border="1" summary="semantics">
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Precondition</th>
+<th>Semantics</th>
+<th>Postcondition</th>
+</tr>
+<tr>
+<td>Sizing constructor</td>
+<td><code>V v (n)</code></td>
+<td><code>n &gt;= 0</code></td>
+<td>Allocates a vector of<code>n</code> elements.</td>
+<td><code>v.size () == n</code>.</td>
+</tr>
+<tr>
+<td>Element access <a href="#element_access_note">[2]</a></td>
+<td><code>v[n]</code></td>
+<td><code>0&lt;n&gt;v.size()</code></td>
+<td>returns the n-th element in v</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Insert</td>
+<td><code>v.insert_element (i, t)</code></td>
+<td><code>0 &lt;= i &lt; v.size ()</code>.</td>
+<td>Inserts an element at <code>v (i)</code> with value <code>t</code>.
+The storage requirement of the Vector may be increased.</td>
+<td><code>v (i)</code> is equal to <code>t</code>.</td>
+</tr>
+<tr>
+<td>Erase</td>
+<td><code>v.erase_element (i)</code></td>
+<td><code>0 &lt;= i &lt; v.size ()</code></td>
+<td>Destroys the element as <code>v (i)</code> and replaces it with the default
+<code>value_type ()</code>.
+The storage requirement of the Vector may be decreased.</td>
+<td><code>v (i)</code> is equal to <code>value_type ()</code>.</td>
+</tr>
+<tr>
+<td>Clear</td>
+<td><code>v.clear ()</code></td>
+<td>&nbsp;</td>
+<td>Equivalent to<br />
+<code>for (i = 0; i &lt; v.size (); ++ i)</code><br />
+&nbsp; <code>v.erase_element (i);</code></td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Resize</td>
+<td><code>v.resize (n)
+<br />v.resize (n, p)</code></td>
+<td>&nbsp;</td>
+<td>Reallocates the vector so that it can hold <code>n</code>
+elements.<br />
+Erases or appends elements in order to bring the vector to the prescribed size. Appended elements copies of <code>value_type()</code>.
+<br />
+When <code>p == false</code> then existing elements are not preserved and elements will not appended as normal. Instead the vector is in the same state as that after an equivalent sizing constructor.</td>
+<td><code>v.size () == n</code>.</td>
+</tr>
+<tr>
+<td>Storage</td>
+<td><code>v.data()</code></td>
+<td></td>
+<td>Returns a reference to the underlying dense storage.</td>
+<td>&nbsp;</td>
+</tr>
+</table>
+<h4>Complexity guarantees</h4>
+<p>The run-time complexity of the sizing constructor is linear in
+the vector's size.</p>
+<p>The run-time complexity of insert_element and erase_element is specific for the
+Vector model and it depends on increases/decreases in storage requirements.</p>
+<p>The run-time complexity of resize is linear in the vector's
+size.</p>
+<h4>Invariants</h4>
+<h4>Models</h4>
+<ul>
+<li><code>vector</code>, <code>bounded_vector</code>, <code>c_vector</code></li>
+<li><code>unit_vector</code>, <code>zero_vector</code>, <code>scalar_vector</code></li>
+<li><code>mapped_vector;</code>, <code>compressed_vector</code>, <code>coordinate_vector</code></li>
+</ul>
+<h4>Notes</h4>
+<p><a name="vector_expression_note">[1]</a>
+As a user you need not care about <tt>Vector</tt> being a refinement of the VectorExpression. Being a refinement of the VectorExpression is only important for the template-expression engine but not the user.</p>
+<p><a name="element_access_note">[2]</a>
+The <code>operator[]</code> is added purely for convenience 
+and compatibility with the <code>std::vector</code>. In uBLAS however, 
+generally <code>operator()</code> is used for indexing because this can be
+used for both vectors and matrices.</p>
+<h2><a name="matrix"></a>Matrix</h2>
+<h4>Description</h4>
+<p>A Matrix describes common aspects of dense, packed and sparse
+matrices.</p>
+<h4>Refinement of</h4>
+<p><a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">DefaultConstructible</a>,
+<a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+<a href="#matrix_expression_note">[1]</a>
+.</p>
+<h4>Associated types</h4>
+<p>In addition to the types defined by <a href="expression_concept.html#matrix_expression">Matrix Expression</a></p>
+<table border="1" summary="types">
+<tbody>
+<tr>
+<td>Public base</td>
+<td>matrix_container&lt;M&gt;</td>
+<td>M must be derived from this public base type.</td>
+</tr>
+<tr>
+<td>Storage array</td>
+<td>M::array_type</td>
+<td>Dense Matrix ONLY. The type of underlying storage array used to store the elements. The array_type must model
+the <a href="storage_concept.html"><b>Storage</b></a> concept.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notation</h4>
+<table border="0" summary="notation">
+<tbody>
+<tr>
+<td><code>M</code></td>
+<td>A type that is a model of Matrix</td>
+</tr>
+<tr>
+<td><code>m</code></td>
+<td>Objects of type <code>M</code></td>
+</tr>
+<tr>
+<td><code>n1, n2, i, j</code></td>
+<td>Objects of a type convertible to <code>size_type</code></td>
+</tr>
+<tr>
+<td><code>t</code></td>
+<td>Object of a type convertible to <code>value_type</code></td>
+</tr>
+<tr>
+<td><code>p</code></td>
+<td>Object of a type convertible to <code>bool</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Definitions</h4>
+<h4>Valid expressions</h4>
+<p>In addition to the expressions defined in <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> the
+following expressions must be valid.</p>
+<table border="1" summary="expressions">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Type requirements</th>
+<th>Return type</th>
+</tr>
+<tr>
+<td>Sizing constructor</td>
+<td><code>M m (n1, n2)</code></td>
+<td>&nbsp;</td>
+<td><code>M</code></td>
+</tr>
+<tr>
+<td>Insert</td>
+<td><code>m.insert_element (i, j, t)</code></td>
+<td><code>m</code> is mutable.</td>
+<td><code>void</code></td>
+</tr>
+<tr>
+<td>Erase</td>
+<td><code>m.erase_element (i, j)</code></td>
+<td><code>m</code> is mutable.</td>
+<td><code>void</code></td>
+</tr>
+<tr>
+<td>Clear</td>
+<td><code>m.clear ()</code></td>
+<td><code>m</code> is mutable.</td>
+<td><code>void</code></td>
+</tr>
+<tr>
+<td>Resize</td>
+<td><code>m.resize (n1, n2)</code><br />
+<code>m.resize (n1, n2, p)</code></td>
+<td><code>m</code> is mutable.</td>
+<td><code>void</code></td>
+</tr>
+<tr>
+<td>Storage</td>
+<td><code>m.data()</code></td>
+<td><code>m</code> is mutable and Dense.</td>
+<td><code>array_type&amp;</code> if <code>m</code> is mutable, <code>const array_type&amp;</code> otherwise</td>
+</tr>
+</tbody>
+</table>
+<h4>Expression semantics</h4>
+<p>Semantics of an expression is defined only where it differs
+from, or is not defined in <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<table border="1" summary="semantics">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Precondition</th>
+<th>Semantics</th>
+<th>Postcondition</th>
+</tr>
+<tr>
+<td>Sizing constructor</td>
+<td><code>M m (n1, n2)</code></td>
+<td><code>n1 &gt;= 0</code> and <code>n2 &gt;= 0</code></td>
+<td>Allocates a matrix of <code>n1</code> rows and <code>n2</code>
+columns.</td>
+<td><code>m.size1 () == n1</code> and <code>m.size2 () ==
+n2</code>.</td>
+</tr>
+<tr>
+<td>Insert</td>
+<td><code>m.insert_element (i, j, t)</code></td>
+<td><code>0 &lt;= i &lt; m.size1 ()</code>,<br />
+<code>0 &lt;= j &lt; m.size2 ()</code>.</td>
+<td>Inserts an element at <code>m (i, j)</code> with value <code>t</code>.
+The storage requirement of the Matrix may be increased.</td>
+<td><code>m (i, j)</code> is equal to <code>t</code>.</td>
+</tr>
+<tr>
+<td>Erase</td>
+<td><code>m.erase_element (i, j)</code></td>
+<td><code>0 &lt;= i &lt; m.size1 ()</code>and <code><br />
+0 &lt;= j &lt; m.size2</code></td>
+<td>Destroys the element as <code>m (i, j)</code> and replaces it with the default
+<code>value_type ()</code>.
+The storage requirement of the Matrix may be decreased.</td>
+<td><code>m (i, j)</code> is equal to <code>value_type ()</code>.</td>
+</tr>
+<tr>
+<td>Clear</td>
+<td><code>m.clear ()</code></td>
+<td>&nbsp;</td>
+<td>Equivalent to<br />
+<code>for (i = 0; i &lt; m.size1 (); ++ i)</code><br />
+&nbsp; <code>for (j = 0; j &lt; m.size2 (); ++ j)</code><br />
+&nbsp; &nbsp; <code>m.erase_element (i, j);</code></td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Resize</td>
+<td><code>m.resize (n1, n2)
+<br />
+m.resize (n1, n2, p)
+</code></td>
+<td>&nbsp;</td>
+<td>Reallocate the matrix so that it can hold <code>n1</code> rows
+and <code>n2</code> columns.<br />
+Erases or appends elements in order to bring the matrix to the
+prescribed size. Appended elements are <code>value_type()</code>
+copies.<br />
+When <code>p == false</code> then existing elements are not preserved and elements will not appended as normal. Instead the matrix is in the same state as that after an equivalent sizing constructor.</td>
+<td><code>m.size1 () == n1</code> and <code>m.size2 () == n2</code>.</td>
+</tr>
+<tr>
+<td>Storage</td>
+<td><code>m.data()</code></td>
+<td></td>
+<td>Returns a reference to the underlying dense storage.</td>
+<td>&nbsp;</td>
+</tbody>
+</table>
+<h4>Complexity guarantees</h4>
+<p>The run-time complexity of the sizing constructor is quadratic
+in the matrix's size.</p>
+<p>The run-time complexity of insert_element and erase_element is specific for the
+Matrix model and it depends on increases/decreases in storage requirements.</p>
+<p>The run-time complexity of resize is quadratic in the matrix's
+size.</p>
+<h4>Invariants</h4>
+<h4>Models</h4>
+<ul>
+<li><code>matrix</code>, <code>bounded_matrix</code>, <code>c_matrix</code></li>
+<li><code>identity_matrix</code> , <code>zero_matrix</code> , <code>scalar_matrix</code></li>
+<li><code>triangular_matrix</code> , <code>symmetric_matrix</code> , <code>banded_matrix</code></li>
+<li><code>mapped_matrix</code> , <code>compressed_matrix</code> , <code>coordinate_matrix</code></li>
+</ul>
+<h4>Notes</h4>
+<p><a name="matrix_expression_note">[1]</a>
+As a user you need not care about <tt>Matrix</tt> being a refinement of the MatrixExpression. Being a refinement of the MatrixExpression is only important for the template-expression engine but not the user.</p>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/expression_concept.html b/doc/expression_concept.html
new file mode 100644
index 0000000..ffbfd14
--- /dev/null
+++ b/doc/expression_concept.html
@@ -0,0 +1,1074 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Expression Concepts</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Expression Concepts</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="scalar_expression"></a>Scalar Expression</h2>
+<h4>Description</h4>
+<p>A Scalar Expression is an expression convertible to a scalar
+type.</p>
+<h4>Refinement of</h4>
+<p>Default Constructible.</p>
+<h4>Associated types</h4>
+<table border="1" summary="associated types">
+<tbody>
+<tr>
+<td>Public base</td>
+<td>scaler_expression&lt;S&gt;</td>
+<td>S must be derived from this public base type.</td>
+</tr>
+<tr>
+<td>Value type</td>
+<td><code>value_type</code></td>
+<td>The type of the scalar expression.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notation</h4>
+<table border="0" summary="notation">
+<tbody>
+<tr>
+<td><code>S</code></td>
+<td>A type that is a model of Scalar Expression</td>
+</tr>
+</tbody>
+</table>
+<h4>Definitions</h4>
+<h4>Valid expressions</h4>
+<p>In addition to the expressions defined in Default Constructible
+the following expressions must be valid.</p>
+<table border="1" summary="expressions">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Type requirements</th>
+<th>Return type</th>
+</tr>
+<tr>
+<td>Evaluation</td>
+<td><code>operator value_type () const</code></td>
+<td>&nbsp;</td>
+<td><code>value_type</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Expression semantics</h4>
+<p>Semantics of an expression is defined only where it differs
+from, or is not defined in Default Constructible.</p>
+<table border="1" summary="semantics">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Precondition</th>
+<th>Semantics</th>
+<th>Postcondition</th>
+</tr>
+<tr>
+<td>Evaluation</td>
+<td><code>operator value_type () const</code></td>
+<td>&nbsp;</td>
+<td>&nbsp; Evaluates the scalar expression.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Complexity guarantees</h4>
+<p>The run-time complexity of the evaluation is specific for the
+evaluated scalar expression.</p>
+<h4>Invariants</h4>
+<h4>Models</h4>
+<ul>
+<li><code>vector_scalar_unary</code></li>
+<li><code>vector_scalar_binary</code></li>
+</ul>
+<h2><a name="vector_expression"></a>Vector Expression</h2>
+<h4>Description</h4>
+<p>A Vector Expression is an expression evaluatable to a vector.
+Vector Expression provides an <a href=
+"iterator_concept.html#indexed_bidirectional_iterator">Indexed Bidirectional
+Iterator</a> or an <a href=
+"iterator_concept.html#indexed_random_access_iterator">Indexed Random Access
+Iterator</a> .</p>
+<h4>Refinement of</h4>
+<p>Default Constructible.</p>
+<h4>Associated types</h4>
+<table border="1" summary="associated types">
+<tbody>
+<tr>
+<td>Public base</td>
+<td>vector_expression&lt;V&gt;</td>
+<td>V must be derived from this public base type.</td>
+</tr>
+<tr>
+<td>Value type</td>
+<td><code>value_type</code></td>
+<td>
+The element type of the vector expression.
+</td>
+</tr>
+<tr>
+<td>Reference type</td>
+<td><code>reference</code></td>
+<td>
+The return type when accessing an element of a vector expression.
+<br />
+Convertable to a<code>value_type</code>.
+</td>
+</tr>
+<tr>
+<td>Const reference type</td>
+<td><code>const_reference</code></td>
+<td>
+The return type when accessing an element of a constant vector expression.
+<br />
+Convertable to a<code>value_type</code>.
+</td>
+</tr>
+<tr>
+<td>Size type</td>
+<td><code>size_type</code></td>
+<td>
+The index type of the vector expression. Am unsigned integral type used to represent size and index values.
+<br />
+Can represent any nonnegative value of <code>difference_type</code>.
+</td>
+</tr>
+<tr>
+<td>Distance type</td>
+<td><code>difference_type</code></td>
+<td>
+A signed integral type used to represent the distance between two of the vector expression&#039;s iterators.
+</td>
+</tr>
+<tr>
+<td>Const iterator type</td>
+<td><code>const_iterator</code></td>
+<td>A type of iterator that may be used to examine a vector
+expression's elements.</td>
+</tr>
+<tr>
+<td>Iterator type</td>
+<td><code>iterator</code></td>
+<td>A type of iterator that may be used to modify a vector
+expression's elements.</td>
+</tr>
+<tr>
+<td>Const reverse iterator type</td>
+<td><code>const_reverse_iterator</code></td>
+<td>A Reverse Iterator adaptor whose base iterator type is the
+vector expression's const iterator type.</td>
+</tr>
+<tr>
+<td>Reverse iterator type</td>
+<td><code>reverse_iterator</code></td>
+<td>A Reverse Iterator adaptor whose base iterator type is the
+vector expression's iterator type.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notation</h4>
+<table border="0" summary="notation">
+<tbody>
+<tr>
+<td><code>V</code></td>
+<td>A type that is a model of Vector Expression</td>
+</tr>
+<tr>
+<td><code>v, v1, v2</code></td>
+<td>Object of type <code>V</code></td>
+</tr>
+<tr>
+<td><code>i</code></td>
+<td>Object of a type convertible to <code>size_type</code></td>
+</tr>
+<tr>
+<td><code>t</code></td>
+<td>Object of a type convertible to <code>value_type</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Definitions</h4>
+<h4>Valid expressions</h4>
+<p>In addition to the expressions defined in Default Constructible
+the following expressions must be valid.</p>
+<table border="1" summary="expressions">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Type requirements</th>
+<th>Return type</th>
+</tr>
+<tr>
+<td rowspan="2">Beginning of range</td>
+<td><code>v.begin ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_iterator</code></td>
+</tr>
+<tr>
+<td><code>v.begin ()</code></td>
+<td><code>v</code> is mutable.</td>
+<td><code>iterator</code></td>
+</tr>
+<tr>
+<td rowspan="2">End of range</td>
+<td><code>v.end ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_iterator</code></td>
+</tr>
+<tr>
+<td><code>v.end ()</code></td>
+<td><code>v</code> is mutable.</td>
+<td><code>iterator</code></td>
+</tr>
+<tr>
+<td>Size</td>
+<td><code>v.size ()</code></td>
+<td>&nbsp;</td>
+<td><code>size_type</code></td>
+</tr>
+<tr>
+<td>Swap</td>
+<td><code>v1.swap (v2)</code></td>
+<td><code>v1</code> and <code>v2</code> are mutable.</td>
+<td><code>void</code></td>
+</tr>
+<tr>
+<td rowspan="2">Beginning of reverse range</td>
+<td><code>v.rbegin ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_reverse_iterator</code></td>
+</tr>
+<tr>
+<td><code>v.rbegin ()</code></td>
+<td><code>v</code> is mutable.</td>
+<td><code>reverse_iterator</code></td>
+</tr>
+<tr>
+<td rowspan="2">End of reverse range</td>
+<td><code>v.rend ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_reverse_iterator</code></td>
+</tr>
+<tr>
+<td><code>v.rend ()</code></td>
+<td><code>v</code> is mutable.</td>
+<td><code>reverse_iterator</code></td>
+</tr>
+<tr>
+<td>Element access</td>
+<td><code>v (i)</code></td>
+<td><code>i</code> is convertible to <code>size_type</code>.</td>
+<td>Convertible to <code>value_type</code>.</td>
+</tr>
+<tr>
+<td rowspan="2">Assignment</td>
+<td><code>v2 = v1</code></td>
+<td><code>v2</code> is mutable and <code>v1</code> is convertible
+to <code>V</code>.</td>
+<td><code>V &amp;</code></td>
+</tr>
+<tr>
+<td><code>v2.assign (v1)</code></td>
+<td><code>v2</code> is mutable and <code>v1</code> is convertible
+to <code>V</code>.</td>
+<td><code>V &amp;</code></td>
+</tr>
+<tr>
+<td rowspan="5">Computed assignment</td>
+<td><code>v2 += v1</code></td>
+<td><code>v2</code> is mutable and <code>v1</code> is convertible
+to <code>V</code>.</td>
+<td><code>V &amp;</code></td>
+</tr>
+<tr>
+<td><code>v2.plus_assign (v1)</code></td>
+<td><code>v2</code> is mutable and <code>v1</code> is convertible
+to <code>V</code>.</td>
+<td><code>V &amp;</code></td>
+</tr>
+<tr>
+<td><code>v2 -= v1</code></td>
+<td><code>v2</code> is mutable and <code>v1</code> is convertible
+to <code>V</code>.</td>
+<td><code>V &amp;</code></td>
+</tr>
+<tr>
+<td><code>v2.minus_assign (v1)</code></td>
+<td><code>v2</code> is mutable and <code>v1</code> is convertible
+to <code>V</code>.</td>
+<td><code>V &amp;</code></td>
+</tr>
+<tr>
+<td><code>v *= t</code></td>
+<td><code>v</code> is mutable and <code>t</code> is convertible to
+<code>value_type</code>.</td>
+<td><code>V &amp;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Expression semantics</h4>
+<p>Semantics of an expression is defined only where it differs
+from, or is not defined in Default Constructible.</p>
+<table border="1" summary="semantics">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Precondition</th>
+<th>Semantics</th>
+<th>Postcondition</th>
+</tr>
+<tr>
+<td>Beginning of range</td>
+<td><code>v.begin ()</code></td>
+<td>&nbsp;</td>
+<td>Returns an iterator pointing to the first element in the vector
+expression.</td>
+<td><code>v.begin ()</code> is either dereferenceable or
+past-the-end. It is past-the-end if and only if <code>v.size () ==
+0</code>.</td>
+</tr>
+<tr>
+<td>End of range</td>
+<td><code>v.end ()</code></td>
+<td>&nbsp;</td>
+<td>Returns an iterator pointing one past the last element in the
+vector expression.</td>
+<td><code>v.end ()</code> is past-the-end.</td>
+</tr>
+<tr>
+<td>Size</td>
+<td><code>v.size ()</code></td>
+<td>&nbsp;</td>
+<td>Returns the size of the vector expression, that is, its number
+of elements.</td>
+<td><code>v.size () &gt;= 0</code></td>
+</tr>
+<tr>
+<td>Swap</td>
+<td><code>v1.swap (v2)</code></td>
+<td>&nbsp;</td>
+<td>Equivalent to <code>swap (v1, v2)</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Beginning of reverse range</td>
+<td><code>v.rbegin ()</code></td>
+<td>&nbsp;</td>
+<td>Equivalent to <code>reverse_iterator (v.end ())</code>.</td>
+<td><code>v.rbegin ()</code> is either dereferenceable or
+past-the-end. It is past-the-end if and only if <code>v.size () ==
+0</code>.</td>
+</tr>
+<tr>
+<td>End of reverse range</td>
+<td><code>v.rend ()</code></td>
+<td>&nbsp;</td>
+<td>Equivalent to <code>reverse_iterator (v.begin ())</code>.</td>
+<td><code>v.rend ()</code> is past-the-end.</td>
+</tr>
+<tr>
+<td>Element access</td>
+<td><code>v (i)</code></td>
+<td><code>0 &lt;= i &lt; v.size ()</code></td>
+<td>Returns the <code>i</code>-th element of the vector
+expression.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td rowspan="2">Assignment</td>
+<td><code>v2 = v1</code></td>
+<td><code>v1.size () == v2.size ()</code></td>
+<td>Assigns every element of the evaluated vector expression
+<code>v1</code> to the corresponding element of <code>v2</code>
+.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>v2.assign (v1)</code></td>
+<td><code>v1.size () == v2.size ()</code></td>
+<td>Assigns every element of <code>v1</code> to the corresponding
+element of <code>v2</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td rowspan="5">Computed assignment</td>
+<td><code>v2 += v1</code></td>
+<td><code>v1.size () == v2.size ()</code></td>
+<td>Adds every element of the evaluated vector expression
+<code>v1</code> to the corresponding element of
+<code>v2</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>v2.plus_assign (v1)</code></td>
+<td><code>v1.size () == v2.size ()</code></td>
+<td>Adds every element of <code>v1</code> to the corresponding
+element of <code>v2</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>v2 -= v1</code></td>
+<td><code>v1.size () == v2.size ()</code></td>
+<td>Subtracts every element of the evaluated vector expression
+<code>v1</code> from the corresponding element of <code>v2</code>
+.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>v2.minus_assign (v1)</code></td>
+<td><code>v1.size () == v2.size ()</code></td>
+<td>Subtracts every element of <code>v1</code> from the
+corresponding element of <code>v2</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>v *= t</code></td>
+<td>&nbsp;</td>
+<td>Multiplies every element of <code>v</code> with <code>t</code>
+.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Complexity guarantees</h4>
+<p>The run-time complexity of <code>begin ()</code> and <code>end
+()</code> is specific for the evaluated vector expression,
+typically amortized constant time.</p>
+<p>The run-time complexity of <code>size ()</code> is constant
+time.</p>
+<p>The run-time complexity of <code>swap ()</code> is specific for
+the evaluated vector expression, typically constant time.</p>
+<p>The run-time complexity of <code>rbegin ()</code> and <code>rend
+()</code> is specific for the evaluated vector expression,
+typically amortized constant time.</p>
+<p>The run-time complexity of the element access is specific for
+the evaluated vector expression, typically amortized constant time
+for the dense and logarithmic for the sparse case.</p>
+<p>The run-time complexity of the arithmetic operations is specific
+for the evaluated vector expressions, typically linear in the size
+of the expressions.</p>
+<h4>Invariants</h4>
+<table border="1" summary="invariants">
+<tbody>
+<tr>
+<td>Valid range</td>
+<td>For any vector expression <code>v</code>, <code>[v.begin (),
+v.end ())</code> is a valid range.</td>
+</tr>
+<tr>
+<td>Completeness</td>
+<td>An algorithm that iterates through the range <code>[v.begin (),
+v.end ())</code> will pass through every element of <code>v</code>
+.</td>
+</tr>
+<tr>
+<td>Valid reverse range</td>
+<td><code>[v.rbegin (), v.rend ())</code> is a valid range.</td>
+</tr>
+<tr>
+<td>Equivalence of ranges</td>
+<td>The distance from <code>v.begin ()</code> to <code>v.end
+()</code> is the same as the distance from <code>v.rbegin ()</code>
+to <code>v.rend ()</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Models</h4>
+<ul>
+<li><code>vector_range;</code></li>
+<li><code>vector_slice</code></li>
+<li><code>matrix_row</code></li>
+<li><code>matrix_column</code></li>
+<li><code>matrix_vector_range</code></li>
+<li><code>matrix_vector_slice</code></li>
+<li><code>vector_unary</code></li>
+<li><code>vector_binary</code></li>
+<li><code>vector_binary_scalar1</code></li>
+<li><code>vector_binary_scalar2</code></li>
+<li><code>matrix_vector_unary1</code></li>
+<li><code>matrix_vector_unary2</code></li>
+<li><code>matrix_vector_binary1</code></li>
+<li><code>matrix_vector_binary2</code></li>
+</ul>
+
+<h2><a name="matrix_expression"></a>Matrix Expression</h2>
+<h4>Description</h4>
+<p>A Matrix Expression is an expression evaluatable to a matrix.
+Matrix Expression provides an <a href=
+"iterator_concept.html#indexed_bidirectional_cr_iterator">Indexed
+Bidirectional Column/Row Iterator</a> or an <a href=
+"iterator_concept.html#indexed_random_access_cr_iterator">Indexed Random
+Access Column/Row Iterator</a> .</p>
+<h4>Refinement of</h4>
+<p>Default Constructible.</p>
+
+<h4>Associated types</h4>
+<h5>immutable types</h5>
+<table border="1" summary="associated immutable types" title="">
+<tbody>
+<tr>
+<td>Public base</td>
+<td><code>matrix_expression&lt;M&gt;</code></td>
+<td>M must be derived from this public base type.</td>
+</tr>
+<tr>
+<td>Value type</td>
+<td><code>value_type</code></td>
+<td>
+The element type of the matrix expression.
+</td>
+</tr>
+<tr>
+<td>Const reference type</td>
+<td><code>const_reference</code></td>
+<td>
+The return type when accessing an element of a constant matrix expression.
+<br />
+Convertable to a <code>value_type</code>.
+</td>
+</tr>
+<tr>
+<td>Size type</td>
+<td><code>size_type</code></td>
+<td>
+The index type of the matrix expression. Am unsigned integral type used to represent size and index values.
+<br />
+Can represent any nonnegative value of <code>difference_type</code>.
+</td>
+</tr>
+<tr>
+<td>Distance type</td>
+<td><code>difference_type</code></td>
+<td>
+A signed integral type used to represent the distance between two of the matrix expression&#039;s iterators.
+</td>
+</tr>
+<tr>
+<td rowspan="2">Const iterator types</td>
+<td><code>const_iterator1</code></td>
+<td>A type of column iterator that may be used to examine a matrix
+expression's elements.</td>
+</tr>
+<tr>
+<td><code>const_iterator2</code></td>
+<td>A type of row iterator that may be used to examine a matrix
+expression's elements.</td>
+</tr>
+<tr>
+<td rowspan="2">Const reverse iterator types</td>
+<td><code>const_reverse_iterator1</code></td>
+<td>A Reverse Iterator adaptor whose base iterator type is the
+matrix expression's const column iterator type.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2</code></td>
+<td>A Reverse Iterator adaptor whose base iterator type is the
+matrix expression's const row iterator type.</td>
+</tr>
+</tbody>
+</table>
+ 
+<h5>mutable types</h5>
+<table border="1" summary="associated mutable types">
+<tbody>
+<tr>
+<td>Reference type</td>
+<td><code>reference</code></td>
+<td>
+The return type when accessing an element of a matrix expression.
+<br />
+Convertable to a <code>value_type</code>.
+</td>
+</tr>
+<tr>
+<td rowspan="2">Iterator types</td>
+<td><code>iterator1</code></td>
+<td>A type of column iterator that may be used to modify a matrix
+expression's elements.</td>
+</tr>
+<tr>
+<td><code>iterator2</code></td>
+<td>A type of row iterator that may be used to modify a matrix
+expression's elements.</td>
+</tr>
+<tr>
+<td rowspan="2">Reverse iterator types</td>
+<td><code>reverse_iterator1</code></td>
+<td>A Reverse Iterator adaptor whose base iterator type is the
+matrix expression's column iterator type.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2</code></td>
+<td>A Reverse Iterator adaptor whose base iterator type is the
+matrix expression's row iterator type.</td>
+</tr>
+</tbody>
+</table>
+
+
+<h4>Notation</h4>
+<table border="0" summary="notation">
+<tbody>
+<tr>
+<td><code>M</code></td>
+<td>A type that is a model of Matrix Expression</td>
+</tr>
+<tr>
+<td><code>m, m1, m2</code></td>
+<td>Object of type <code>M</code></td>
+</tr>
+<tr>
+<td><code>i, j</code></td>
+<td>Objects of a type convertible to <code>size_type</code></td>
+</tr>
+<tr>
+<td><code>t</code></td>
+<td>Object of a type convertible to <code>value_type</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Definitions</h4>
+<h4>Valid expressions</h4>
+<p>In addition to the expressions defined in Default Constructible
+the following expressions must be valid.</p>
+
+<h5>immutable expressions</h5>
+<table border="1" summary="expressions">
+<thead>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Type requirements</th>
+<th>Return type</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td rowspan="2">Size</td>
+<td><code>m.size1 ()</code></td>
+<td>&nbsp;</td>
+<td><code>size_type</code></td>
+</tr>
+<tr>
+<td><code>m.size2 ()</code></td>
+<td>&nbsp;</td>
+<td><code>size_type</code></td>
+</tr>
+</tbody>
+</table>
+
+<h5>possibly mutable expressions</h5>
+<table border="1" summary="expressions">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Type requirements</th>
+<th>Return type</th>
+</tr>
+<tr>
+<td rowspan="4">Beginning of range</td>
+<td><code>m.begin1 ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_iterator1</code></td>
+</tr>
+<tr>
+<td><code>m.begin2 ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_iterator2</code></td>
+</tr>
+<tr>
+<td><code>m.begin1 ()</code></td>
+<td><code>m</code> is mutable.&nbsp;</td>
+<td><code>iterator1</code></td>
+</tr>
+<tr>
+<td><code>m.begin2 ()</code></td>
+<td><code>m</code> is mutable.</td>
+<td><code>iterator2</code></td>
+</tr>
+<tr>
+<td rowspan="4">End of range</td>
+<td><code>m.end1 ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_iterator1</code></td>
+</tr>
+<tr>
+<td><code>m.end2 ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_iterator2</code></td>
+</tr>
+<tr>
+<td><code>m.end1 ()</code></td>
+<td><code>m</code> is mutable.&nbsp;</td>
+<td><code>iterator1</code></td>
+</tr>
+<tr>
+<td><code>m.end2 ()</code></td>
+<td><code>m</code> is mutable.</td>
+<td><code>iterator2</code></td>
+</tr>
+<tr>
+<td>Swap</td>
+<td><code>m1.swap (m2)</code></td>
+<td><code>m1</code> and <code>m2</code> are mutable.&nbsp;</td>
+<td><code>void</code></td>
+</tr>
+<tr>
+<td rowspan="4">Beginning of reverse range</td>
+<td><code>m.rbegin1 ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_reverse_iterator1</code></td>
+</tr>
+<tr>
+<td><code>m.rbegin2 ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_reverse_iterator2</code></td>
+</tr>
+<tr>
+<td><code>m.rbegin1 ()</code></td>
+<td><code>m</code> is mutable.&nbsp;</td>
+<td><code>reverse_iterator1</code></td>
+</tr>
+<tr>
+<td><code>m.rbegin2 ()</code></td>
+<td><code>m</code> is mutable.</td>
+<td><code>reverse_iterator2</code></td>
+</tr>
+<tr>
+<td rowspan="4">End of reverse range</td>
+<td><code>m.rend1 ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_reverse_iterator1</code></td>
+</tr>
+<tr>
+<td><code>m.rend2 ()</code></td>
+<td>&nbsp;</td>
+<td><code>const_reverse_iterator2</code></td>
+</tr>
+<tr>
+<td><code>m.rend1 ()</code></td>
+<td><code>m</code> is mutable.</td>
+<td><code>reverse_iterator1</code></td>
+</tr>
+<tr>
+<td><code>m.rend2 ()</code></td>
+<td><code>m</code> is mutable.</td>
+<td><code>reverse_iterator2</code></td>
+</tr>
+<tr>
+<td>Element access</td>
+<td><code>m (i, j)</code></td>
+<td><code>i</code> and <code>j</code> are convertible to
+<code>size_type</code> .</td>
+<td>Convertible to <code>value_type</code>.</td>
+</tr>
+<tr>
+<td rowspan="2">Assignment</td>
+<td><code>m2 = m1</code></td>
+<td><code>m2</code> is mutable and <code>m1</code> is convertible
+to <code>M</code>.</td>
+<td><code>M &amp;</code></td>
+</tr>
+<tr>
+<td><code>m2.assign (m1)</code></td>
+<td><code>m2</code> is mutable and <code>m1</code> is convertible
+to <code>M</code>.</td>
+<td><code>M &amp;</code></td>
+</tr>
+<tr>
+<td rowspan="5">Computed assignment</td>
+<td><code>m2 += m1</code></td>
+<td><code>m2</code> is mutable and <code>m1</code> is convertible
+to <code>M</code>.</td>
+<td><code>M &amp;</code></td>
+</tr>
+<tr>
+<td><code>m2.plus_assign (m1)</code></td>
+<td><code>m2</code> is mutable and <code>m1</code> is convertible
+to <code>M</code>.</td>
+<td><code>M &amp;</code></td>
+</tr>
+<tr>
+<td><code>m2 -= m1</code></td>
+<td><code>m2</code> is mutable and <code>m1</code> is convertible
+to <code>M</code>.</td>
+<td><code>M &amp;</code></td>
+</tr>
+<tr>
+<td><code>m2.minus_assign (m1)</code></td>
+<td><code>m2</code> is mutable and <code>m1</code> is convertible
+to <code>M</code>.</td>
+<td><code>M &amp;</code></td>
+</tr>
+<tr>
+<td><code>m *= t</code></td>
+<td><code>m</code> is mutable and <code>t</code> is convertible to
+<code>value_type</code>.</td>
+<td><code>M &amp;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Expression semantics</h4>
+<p>Semantics of an expression is defined only where it differs
+from, or is not defined in Default Constructible.</p>
+<table border="1" summary="semantics">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Precondition</th>
+<th>Semantics</th>
+<th>Postcondition</th>
+</tr>
+<tr>
+<td rowspan="2">Beginning of range</td>
+<td><code>m.begin1 ()</code></td>
+<td>&nbsp;</td>
+<td>Returns an iterator pointing to the first element in the first
+column of a matrix expression.</td>
+<td><code>m.begin1 ()</code> is either dereferenceable or
+past-the-end. It is past-the-end if and only if <code>m.size1 () ==
+0</code>.</td>
+</tr>
+<tr>
+<td><code>m.begin2 ()</code></td>
+<td>&nbsp;</td>
+<td>Returns an iterator pointing to the first element in the first
+row of a matrix expression.</td>
+<td><code>m.begin2 ()</code> is either dereferenceable or
+past-the-end. It is past-the-end if and only if <code>m.size2 () ==
+0</code>.</td>
+</tr>
+<tr>
+<td rowspan="2">End of range</td>
+<td><code>m.end1 ()</code></td>
+<td>&nbsp;</td>
+<td>Returns an iterator pointing one past the last element in the
+matrix expression.</td>
+<td><code>m.end1 ()</code> is past-the-end.</td>
+</tr>
+<tr>
+<td><code>m.end2 ()</code></td>
+<td>&nbsp;</td>
+<td>Returns an iterator pointing one past the last element in the
+matrix expression.</td>
+<td><code>m.end2 ()</code> is past-the-end.</td>
+</tr>
+<tr>
+<td rowspan="2">Size</td>
+<td><code>m.size1 ()</code></td>
+<td>&nbsp;</td>
+<td>Returns the number of rows of the matrix expression.</td>
+<td><code>m.size1 () &gt;= 0</code></td>
+</tr>
+<tr>
+<td><code>m.size2 ()</code></td>
+<td>&nbsp;</td>
+<td>Returns the number of columns of the matrix expression.</td>
+<td><code>m.size2 () &gt;= 0</code></td>
+</tr>
+<tr>
+<td>Swap</td>
+<td><code>m1.swap (m2)</code></td>
+<td>&nbsp;</td>
+<td>Equivalent to <code>swap (m1, m2)</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td rowspan="2">Beginning of reverse range</td>
+<td><code>m.rbegin1 ()</code></td>
+<td>&nbsp;</td>
+<td>Equivalent to <code>reverse_iterator1 (m.end1 ())</code>.</td>
+<td><code>m.rbegin1 ()</code> is either dereferenceable or
+past-the-end. It is past-the-end if and only if <code>m.size1 () ==
+0</code>.</td>
+</tr>
+<tr>
+<td><code>m.rbegin2 ()</code></td>
+<td>&nbsp;</td>
+<td>Equivalent to <code>reverse_iterator2 (m.end2 ())</code>.</td>
+<td><code>m.rbegin2 ()</code> is either dereferenceable or
+past-the-end. It is past-the-end if and only if <code>m.size2 () ==
+0</code>.</td>
+</tr>
+<tr>
+<td rowspan="2">End of reverse range</td>
+<td><code>m.rend1 ()</code></td>
+<td>&nbsp;</td>
+<td>Equivalent to <code>reverse_iterator1 (m.begin1
+())</code>.</td>
+<td><code>m.rend1 ()</code> is past-the-end.</td>
+</tr>
+<tr>
+<td><code>m.rend2 ()</code></td>
+<td>&nbsp;</td>
+<td>Equivalent to <code>reverse_iterator2 (m.begin2
+())</code>.</td>
+<td><code>m.rend2 ()</code> is past-the-end.</td>
+</tr>
+<tr>
+<td>Element access</td>
+<td><code>m (i, j)</code></td>
+<td><code>0 &lt;= i &lt; m.size1 ()</code> and <code>0 &lt;= j &lt;
+m.size2 ()</code></td>
+<td>Returns the <code>j</code>-th element of the <code>i</code>-th
+row of the matrix expression.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td rowspan="2">Assignment</td>
+<td><code>m2 = m1</code></td>
+<td><code>m1.size1 () == m2.size1 ()</code> and <code><br />
+m1.size2 () == m2.size2 ()</code></td>
+<td>Assigns every element of the evaluated matrix expression
+<code>m1</code> to the corresponding element of <code>m2</code>
+.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>m2.assign (m1)</code></td>
+<td><code>m1.size1 () == m2.size1 ()</code> and <code><br />
+m1.size2 () == m2.size2 ()</code></td>
+<td>Assigns every element of <code>m1</code> to the corresponding
+element of <code>m2</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td rowspan="5">Computed assignment</td>
+<td><code>m2 += m1</code></td>
+<td><code>m1.size1 () == m2.size1 ()</code> and <code><br />
+m1.size2 () == m2.size2 ()</code></td>
+<td>Adds every element of the evaluated matrix expression
+<code>m1</code> to the corresponding element of
+<code>m2</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>m2.plus_assign (m1)</code></td>
+<td><code>m1.size1 () == m2.size1 ()</code> and <code><br />
+m1.size2 () == m2.size2 ()</code></td>
+<td>Adds every element of <code>m1</code> to the corresponding
+element of <code>m2</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>m2 -= m1</code></td>
+<td><code>m1.size1 () == m2.size1 ()</code> and <code><br />
+m1.size2 () == m2.size2 ()</code></td>
+<td>Subtracts every element of the evaluated matrix expression
+<code>m1</code> from the corresponding element of <code>m2</code>
+.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>m2.minus_assign (m1)</code></td>
+<td><code>m1.size1 () == m2.size1 ()</code> and <code><br />
+m1.size2 () == m2.size2 ()</code></td>
+<td>Subtracts every element of <code>m1</code> from the
+corresponding element of <code>m2</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>m *= t</code></td>
+<td>&nbsp;</td>
+<td>Multiplies every element of <code>m</code> with <code>t</code>
+.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Complexity guarantees</h4>
+<p>The run-time complexity of <code>begin1 ()</code>, <code>begin2
+()</code> , <code>end1 ()</code> and <code>end2 ()</code> is
+specific for the evaluated matrix expression.</p>
+<p>The run-time complexity of <code>size1 ()</code> and <code>size2
+()</code> is constant time.</p>
+<p>The run-time complexity of <code>swap ()</code> is specific for
+the evaluated matrix expression, typically constant time.</p>
+<p>The run-time complexity of <code>rbegin1 ()</code>,
+<code>rbegin2 ()</code> , <code>rend1 ()</code> and <code>rend2
+()</code> is specific for the evaluated matrix expression.</p>
+<p>The run-time complexity of the element access is specific for
+the evaluated matrix expression, typically amortized constant time
+for the dense and logarithmic for the sparse case.</p>
+<p>The run-time complexity of the arithmetic operations is specific
+for the evaluated matrix expressions, typically quadratic in the
+size of the proxies.</p>
+<h4>Invariants</h4>
+<table border="1" summary="invariants">
+<tbody>
+<tr>
+<td>Valid range</td>
+<td>For any matrix expression <code>m</code>, <code>[m.begin1 (),
+m.end1 ())</code> and <code>[m.begin2 (), m.end2 ())</code> are
+valid ranges.</td>
+</tr>
+<tr>
+<td>Completeness</td>
+<td>An algorithm that iterates through the range <code>[m.begin1
+(), m.end1 ())</code> will pass through every row of <code>m</code>
+, an algorithm that iterates through the range <code>[m.begin2 (),
+m.end2 ())</code> will pass through every column of <code>m</code>
+.</td>
+</tr>
+<tr>
+<td>Valid reverse range</td>
+<td><code>[m.rbegin1 (), m.rend1 ())</code> and <code>[m.rbegin2
+(), m.rend2 ())</code> are valid ranges.</td>
+</tr>
+<tr>
+<td>Equivalence of ranges</td>
+<td>The distance from <code>m.begin1 ()</code> to <code>m.end1
+()</code> is the same as the distance from <code>m.rbegin1
+()</code> to <code>m.rend1 ()</code> and the distance from
+<code>m.begin2 ()</code> to <code>m.end2 ()</code> is the same as
+the distance from <code>m.rbegin2 ()</code> to <code>m.rend2
+()</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Models</h4>
+<ul>
+<li><code>matrix_range</code></li>
+<li><code>matrix_slice;</code></li>
+<li><code>triangular_adaptor</code></li>
+<li><code>symmetric_adaptor</code></li>
+<li><code>banded_adaptor</code></li>
+<li><code>vector_matrix_binary</code></li>
+<li><code>matrix_unary1</code></li>
+<li><code>matrix_unary2</code></li>
+<li><code>matrix_binary</code></li>
+<li><code>matrix_binary_scalar1</code></li>
+<li><code>matrix_binary_scalar2</code></li>
+<li><code>matrix_matrix_binary</code></li>
+</ul>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/hermitian.html b/doc/hermitian.html
new file mode 100644
index 0000000..f6a4f62
--- /dev/null
+++ b/doc/hermitian.html
@@ -0,0 +1,597 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Hermitian Matrix</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Hermitian Matrix</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="hermitian_matrix"></a>Hermitian Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>hermitian_matrix&lt;T, F1, F2,
+A&gt;</code> is the base container adaptor for hermitian matrices.
+For a <em>(n x n</em> )-dimensional hermitian matrix and <em>0
+&lt;= i &lt; n</em>, <em>0 &lt;= j &lt; n</em> holds
+<em>h</em><sub><em>i, j</em></sub> <em>= h</em><sub><em>j,
+i</em></sub><sup><em>-</em></sup>. The storage of hermitian
+matrices is packed.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/hermitian.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    hermitian_matrix&lt;std::complex&lt;double&gt;, lower&gt; ml (3, 3);
+    for (unsigned i = 0; i &lt; ml.size1 (); ++ i) {
+        for (unsigned j = 0; j &lt; i; ++ j)
+            ml (i, j) = std::complex&lt;double&gt; (3 * i + j, 3 * i + j);
+        ml (i, i) = std::complex&lt;double&gt; (4 * i, 0);
+    }
+    std::cout &lt;&lt; ml &lt;&lt; std::endl;
+    hermitian_matrix&lt;std::complex&lt;double&gt;, upper&gt; mu (3, 3);
+    for (unsigned i = 0; i &lt; mu.size1 (); ++ i) {
+        mu (i, i) = std::complex&lt;double&gt; (4 * i, 0);
+        for (unsigned j = i + 1; j &lt; mu.size2 (); ++ j)
+            mu (i, j) = std::complex&lt;double&gt; (3 * i + j, 3 * i + j);
+    }
+    std::cout &lt;&lt; mu &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header hermitian.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F1</code></td>
+<td>Functor describing the type of the hermitian matrix. <a href=
+"#hermitian_matrix_1">[1]</a></td>
+<td><code>lower</code></td>
+</tr>
+<tr>
+<td><code>F2</code></td>
+<td>Functor describing the storage organization. <a href=
+"#hermitian_matrix_2">[2]</a></td>
+<td><code>row_major</code></td>
+</tr>
+<tr>
+<td><code>A</code></td>
+<td>The type of the adapted array. <a href=
+"#hermitian_matrix_3">[3]</a></td>
+<td><code>unbounded_array&lt;T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;hermitian_matrix&lt;T, F1, F2, A&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>hermitian_matrix ()</code></td>
+<td>Allocates an uninitialized <code>hermitian_matrix</code> that
+holds zero rows of zero elements.</td>
+</tr>
+<tr>
+<td><code>hermitian_matrix (size_type size)</code></td>
+<td>Allocates an uninitialized <code>hermitian_matrix</code> that
+holds <code>size</code> rows of <code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>hermitian_matrix (const hermitian_matrix
+&amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_matrix (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, bool preserve =
+true)</code></td>
+<td>Reallocates a <code>hermitian_matrix</code> to hold
+<code>size</code> rows of <code>size</code> elements. The existing
+elements of the <code>hermitian_matrix</code> are preseved when
+specified.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns a <code>const</code> reference of the <code>j</code>
+-th element in the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>hermitian_matrix &amp;operator = (const hermitian_matrix
+&amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>hermitian_matrix &amp;assign_temporary (hermitian_matrix
+&amp;m)</code></td>
+<td>Assigns a temporary. May change the hermitian matrix
+<code>m</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_matrix &amp;operator = (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_matrix &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the hermitian matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_matrix &amp;operator += (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the hermitian matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_matrix &amp;plus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a matrix expression to the hermitian matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_matrix &amp;operator -= (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the hermitian matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_matrix &amp;minus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a matrix expression from the hermitian matrix. Left
+and right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+hermitian_matrix &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the hermitian matrix
+with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+hermitian_matrix &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the hermitian matrix
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (hermitian_matrix &amp;m)</code></td>
+<td>Swaps the contents of the hermitian matrices.</td>
+</tr>
+<tr>
+<td><code>void insert (size_type i, size_type j, const_reference
+t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>j</code>-th
+element of the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void erase (size_type i, size_type j)</code></td>
+<td>Erases the value at the <code>j</code>-th elemenst of the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the matrix.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>hermitian_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>hermitian_matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="hermitian_matrix_1" id="hermitian_matrix_1">[1]</a>
+Supported parameters for the type of the hermitian matrix are
+<code>lower</code> and <code>upper</code>.</p>
+<p><a name="hermitian_matrix_2" id="hermitian_matrix_2">[2]</a>
+Supported parameters for the storage organization are
+<code>row_major</code> and <code>column_major</code>.</p>
+<p><a name="hermitian_matrix_3" id="hermitian_matrix_3">[3]</a>
+Supported parameters for the adapted array are
+<code>unbounded_array&lt;T&gt;</code> ,
+<code>bounded_array&lt;T&gt;</code> and
+<code>std::vector&lt;T&gt;</code> .</p>
+<h2><a name="hermitian_adaptor"></a>Hermitian Adaptor</h2>
+<h4>Description</h4>
+<p>The templated class <code>hermitian_adaptor&lt;M, F&gt;</code>
+is a hermitian matrix adaptor for other matrices.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/hermitian.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;std::complex&lt;double&gt; &gt; m (3, 3);
+    hermitian_adaptor&lt;matrix&lt;std::complex&lt;double&gt; &gt;, lower&gt; hal (m);
+    for (unsigned i = 0; i &lt; hal.size1 (); ++ i) {
+        for (unsigned j = 0; j &lt; i; ++ j)
+            hal (i, j) = std::complex&lt;double&gt; (3 * i + j, 3 * i + j);
+        hal (i, i) = std::complex&lt;double&gt; (4 * i, 0);
+    }
+    std::cout &lt;&lt; hal &lt;&lt; std::endl;
+    hermitian_adaptor&lt;matrix&lt;std::complex&lt;double&gt; &gt;, upper&gt; hau (m);
+    for (unsigned i = 0; i &lt; hau.size1 (); ++ i) {
+        hau (i, i) = std::complex&lt;double&gt; (4 * i, 0);
+        for (unsigned j = i + 1; j &lt; hau.size2 (); ++ j)
+            hau (i, j) = std::complex&lt;double&gt; (3 * i + j, 3 * i + j);
+    }
+    std::cout &lt;&lt; hau &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header hermitian.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>M</code></td>
+<td>The type of the adapted matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>Functor describing the type of the hermitian adaptor. <a href=
+"#hermitian_adaptor_1">[1]</a></td>
+<td><code>lower</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;hermitian_adaptor&lt;M, F&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>hermitian_adaptor (matrix_type &amp;data)</code></td>
+<td>Constructs a <code>hermitian_adaptor</code> of a matrix.</td>
+</tr>
+<tr>
+<td><code>hermitian_adaptor (const hermitian_adaptor
+&amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_adaptor (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns a <code>const</code> reference of the <code>j</code>
+-th element in the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>hermitian_adaptor &amp;operator = (const
+hermitian_adaptor &amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>hermitian_adaptor &amp;assign_temporary
+(hermitian_adaptor &amp;m)</code></td>
+<td>Assigns a temporary. May change the hermitian adaptor
+<code>m</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_adaptor &amp;operator = (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_adaptor &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the hermitian adaptor. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_adaptor &amp;operator += (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the hermitian adaptor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_adaptor &amp;plus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a matrix expression to the hermitian adaptor. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_adaptor &amp;operator -= (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the hermitian adaptor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+hermitian_adaptor &amp;minus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a matrix expression from the hermitian adaptor. Left
+and right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+hermitian_adaptor &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the hermitian
+adaptor with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+hermitian_adaptor &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the hermitian adaptor
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (hermitian_adaptor &amp;m)</code></td>
+<td>Swaps the contents of the hermitian adaptors.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>hermitian_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>hermitian_adaptor</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="hermitian_adaptor_1" id="hermitian_adaptor_1">[1]</a>
+Supported parameters for the type of the hermitian adaptor are
+<code>lower</code> and <code>upper</code>.</p>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/index.html b/doc/index.html
new file mode 100644
index 0000000..6a3a15d
--- /dev/null
+++ b/doc/index.html
@@ -0,0 +1,391 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Boost Basic Linear Algebra</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" alt="logo"/>Basic Linear Algebra Library</h1>
+<div class="toc" id="toc"></div>
+
+<p>uBLAS is a C++ template class library that provides <a href="http://www.netlib.org/blas">BLAS</a> level 1, 2, 3
+functionality for dense, packed and sparse matrices. The design and implementation unify mathematical notation via
+operator overloading and efficient code generation via expression templates.</p>
+
+<h2>Functionality</h2>
+
+<p>uBLAS provides templated C++ classes for dense, unit and sparse vectors, dense, identity, triangular, banded,
+symmetric, hermitian and sparse matrices. Views into vectors and matrices can be constructed via ranges, slices, 
+adaptor classes and indirect arrays. The library covers the usual basic linear algebra operations on vectors and matrices: reductions like
+different norms, addition and subtraction of vectors and matrices and multiplication with a scalar, inner and outer
+products of vectors, matrix vector and matrix matrix products and triangular solver. The glue between containers, views
+and expression templated operations is a mostly <a href="http://www.sgi.com/tech/stl">STL</a> conforming iterator interface.</p>
+
+<h2>Documentation</h2>
+
+<ul>
+<li><big><a href="overview.html">Overview</a></big>
+<ul>
+<li><a href="overview.html#rationale">Rationale</a>
+</li>
+
+<li><a href="overview.html#functionality">Functionality</a>
+</li>
+
+<li><a href="types_overview.html">Overview of Matrix- and Vector-Types</a>
+</li>
+
+<li><a href="operations_overview.html">Overview of Matrix and Vector Operations</a>
+</li>
+
+<li><a href="#further_information">Effective uBLAS and further information</a>
+</li>
+
+<li><a href="options.html">Macros and Preprocessor Options</a>
+</li>
+</ul>
+</li>
+
+<li><a href="vector.html">Vector</a>
+<ul>
+<li><a href="vector.html#vector">Vector</a>
+</li>
+
+<li><a href="vector.html#unit_vector">Unit Vector</a>
+</li>
+
+<li><a href="vector.html#zero_vector">Zero Vector</a>
+</li>
+
+<li><a href="vector.html#scalar_vector">Scalar Vector</a>
+</li>
+</ul>
+</li>
+
+<li><a href="vector_sparse.html">Sparse Vector</a>
+<ul>
+<li><a href="vector_sparse.html#mapped_vector">Mapped Vector</a>
+</li>
+
+<li><a href="vector_sparse.html#compressed_vector">Compressed Vector</a>
+</li>
+
+<li><a href="vector_sparse.html#coordinate_vector">Coordinate Vector</a>
+</li>
+</ul>
+</li>
+
+<li><a href="vector_proxy.html">Vector Proxies</a>
+<ul>
+<li><a href="vector_proxy.html#vector_range">Vector Range</a>
+</li>
+
+<li><a href="vector_proxy.html#vector_slice">Vector Slice</a>
+</li>
+</ul>
+</li>
+
+<li><a href="vector_expression.html">Vector Expressions</a>
+<ul>
+<li><a href="vector_expression.html#vector_expression">Vector Expression</a>
+</li>
+
+<li><a href="vector_expression.html#vector_references">Vector References</a>
+</li>
+
+<li><a href="vector_expression.html#vector_operations">Vector Operations</a>
+</li>
+
+<li><a href="vector_expression.html#vector_reductions">Vector Reductions</a>
+</li>
+</ul>
+</li>
+
+<li><a href="matrix.html">Matrix</a>
+<ul>
+<li><a href="matrix.html#matrix">Matrix</a>
+</li>
+
+<li><a href="matrix.html#identity_matrix">Identity Matrix</a>
+</li>
+
+<li><a href="matrix.html#zero_matrix">Zero Matrix</a>
+</li>
+
+<li><a href="matrix.html#scalar_matrix">Scalar Matrix</a>
+</li>
+</ul>
+</li>
+
+<li><a href="triangular.html">Triangular Matrix</a>
+<ul>
+<li><a href="triangular.html#triangular_matrix">Triangular Matrix</a>
+</li>
+
+<li><a href="triangular.html#triangular_adaptor">Triangular Adaptor</a>
+</li>
+</ul>
+</li>
+
+<li><a href="symmetric.html">Symmetric Matrix</a>
+<ul>
+<li><a href="symmetric.html#symmetric_matrix">Symmetric Matrix</a>
+</li>
+
+<li><a href="symmetric.html#symmetric_adaptor">Symmetric Adaptor</a>
+</li>
+</ul>
+</li>
+
+<li><a href="hermitian.html">Hermitian Matrix</a>
+<ul>
+<li><a href="hermitian.html#hermitian_matrix">Hermitian Matrix</a>
+</li>
+
+<li><a href="hermitian.html#hermitian_adaptor">Hermitian Adaptor</a>
+</li>
+</ul>
+</li>
+
+<li><a href="banded.html">Banded Matrix</a>
+<ul>
+<li><a href="banded.html#banded_matrix">Banded Matrix</a>
+</li>
+
+<li><a href="banded.html#banded_adaptor">Banded Adaptor</a>
+</li>
+</ul>
+</li>
+
+<li><a href="matrix_sparse.html">Sparse Matrix</a>
+<ul>
+<li><a href="matrix_sparse.html#mapped_matrix">Mapped Matrix</a>
+</li>
+
+<li><a href="matrix_sparse.html#compressed_matrix">Compressed Matrix</a>
+</li>
+
+<li><a href="matrix_sparse.html#coordinate_matrix">Coordinate Matrix</a>
+</li>
+</ul>
+</li>
+
+<li><a href="matrix_proxy.html">Matrix Proxies</a>
+<ul>
+<li><a href="matrix_proxy.html#matrix_row">Matrix Row</a>
+</li>
+
+<li><a href="matrix_proxy.html#matrix_column">Matrix Column</a>
+</li>
+
+<li><a href="matrix_proxy.html#vector_range">Vector Range</a>
+</li>
+
+<li><a href="matrix_proxy.html#vector_slice">Vector Slice</a>
+</li>
+
+<li><a href="matrix_proxy.html#matrix_range">Matrix Range</a>
+</li>
+
+<li><a href="matrix_proxy.html#matrix_slice">Matrix Slice</a>
+</li>
+</ul>
+</li>
+
+<li><a href="matrix_expression.html">Matrix Expressions</a>
+<ul>
+<li><a href="matrix_expression.html#matrix_expression">Matrix Expression</a>
+</li>
+
+<li><a href="matrix_expression.html#matrix_references">Matrix References</a>
+</li>
+
+<li><a href="matrix_expression.html#matrix_operations">Matrix Operations</a>
+</li>
+
+<li><a href="matrix_expression.html#matrix_vector_operations">Matrix Vector Operations</a>
+</li>
+
+<li><a href="matrix_expression.html#matrix_matrix_operations">Matrix Matrix Operations</a>
+</li>
+</ul>
+</li>
+
+<li>Storage and special containers
+
+<ul>
+<li><a href="unbounded_array.html">Unbounded Array</a>
+</li>
+
+<li><a href="bounded_array.html">Bounded Array</a>
+</li>
+
+<li><a href="range.html#range">Range</a>
+</li>
+
+<li><a href="range.html#slice">Slice</a>
+</li>
+</ul></li>
+
+<li><a href="storage_sparse.html">Sparse Storage</a>
+<ul>
+<li><a href="storage_sparse.html#map_std">Default Standard Map</a>
+</li>
+
+<li><a href="storage_sparse.html#map_array">Map Array</a>
+</li>
+</ul>
+</li>
+
+<li>Operations &amp; Functions
+
+<ul>
+<li><a href="products.html">Special Products</a>
+</li>
+
+<li><a href="blas.html">BLAS</a>
+</li>
+</ul></li>
+
+<li>uBLAS Concept definitions
+
+<ul>
+<li><a href="container_concept.html">Container Concepts</a>
+<ul>
+<li><a href="container_concept.html#vector">Vector</a>
+</li>
+
+<li><a href="container_concept.html#matrix">Matrix</a>
+</li>
+</ul>
+</li>
+
+<li><a href="expression_concept.html">Expression Concepts</a>
+<ul>
+<li><a href="expression_concept.html#scalar_expression">Scalar Expression</a>
+</li>
+
+<li><a href="expression_concept.html#vector_expression">Vector Expression</a>
+</li>
+
+<li><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+</li>
+</ul>
+</li>
+
+<li><a href="storage_concept.html">Storage Concept</a>
+</li>
+
+<li><a href="iterator_concept.html">Iterator Concepts</a>
+<ul>
+<li><a href="iterator_concept.html#indexed_bidirectional_iterator">Indexed Bidirectional Iterator</a>
+</li>
+
+<li><a href="iterator_concept.html#indexed_random_access_iterator">Indexed Random Access Iterator</a>
+</li>
+
+<li><a href="iterator_concept.html#indexed_bidirectional_cr_iterator">Indexed Bidirectional Column/Row Iterator</a>
+</li>
+
+<li><a href="iterator_concept.html#indexed_random_access_cr_iterator">Indexed Random Access Column/Row Iterator</a>
+</li>
+</ul>
+</li>
+</ul></li>
+</ul>
+
+<a name="further_information" id="further_information"></a>
+<h2>Known limitations:</h2>
+
+<ul type="disc">
+<li>The implementation assumes a linear memory address model.</li>
+
+<li>Tuning was focussed on dense matrices.</li>
+</ul>
+
+<h2>Further Information</h2>
+
+<h3>Project Location and Download</h3>
+
+<p>The latest stable release of uBLAS is part of the <a href="http://www.boost.org">Boost</a> libraries.</p>
+
+<h3>Documentation and Discussion</h3>
+
+<p>Visit the <a href="http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Effective_UBLAS">Effective
+uBLAS</a> wiki for up to date information and contributions.</p>
+
+<p>There is also an active uBLAS <a href="http://lists.boost.org/">mailing list</a> where uBLAS specific user and
+development questions are answered.</p>
+
+<h3>uBLAS and Boost Project</h3>
+
+<p>There is also an active uBLAS <a href="http://lists.boost.org/">mailing list</a> where uBLAS specific from the
+latest uBLAS project code. You can <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/boost">view</a> the Boost
+CVS archive directly. You will find the library <a href=
+"http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/boost/boost/boost/numeric/ublas/">here</a>. Documentation and test
+programs reside <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/boost/boost/libs/numeric/ublas/">here</a>.</p>
+
+<h2>Authors and Credits</h2>
+
+<p>uBLAS initially was written by Joerg Walter and Mathias Koch. We would like to thank all, which supported and
+contributed to the development of this library: David Abrahams, Ed Brey, Fernando Cacciola, Juan Jose Gomez Cadenas,
+Beman Dawes, Matt Davies, Bob Fletcher, Kresimir Fresl, Joachim Kessel, Patrick Kowalzick, Toon Knapen, Hendrik Kueck,
+John Maddock, Jens Maurer, Alexei Novakov, Gary Powell, Joachim Pyras, Peter Schmitteckert, Jeremy Siek, Markus Steffl,
+Michael Stevens, Benedikt Weber, Martin Weiser, Gunter Winkler, Marc Zimmermann, Marco Guazzone, Nasos Iliopoulus, the members of <a href="http://www.boost.org">Boost</a> and all others contributors around the world. I promise I will try to add their names to this list.</p>
+<p>
+This library is currently maintained by <a="mailto:david.bellot@gmail.com">David Bellot</a>.
+<h2>Frequently Asked Questions</h2>
+
+<p>Q: Should I use uBLAS for new projects?<br/>
+A: At the time of writing (09/2012) there are a lot of good matrix libraries available, e.g., 
+<a href="http://www.simunova.com" target="_blank">MTL4</a>,
+<a href="http://arma.sourceforge.net" target="_blank">armadillo</a>,
+<a href="http://eigen.tuxfamily.org" target="_blank">eigen</a>. uBLAS offers a stable, well tested set of vector and 
+matrix classes, the typical operations for linear algebra and solvers for triangular systems of equations. uBLAS offers 
+dense, structured and sparse matrices - all using similar interfaces. And finally uBLAS offers good (but not outstanding) 
+performance. On the other side, the last major improvement of uBLAS was in 2008 and no significant change was committed 
+since 2009. So one should ask himself some questions to aid the decision: <i>Availability?</i> uBLAS is part of boost 
+and thus available in many environments. <i>Easy to use?</i> uBLAS is easy to use for simple things, but needs decent
+C++ knowledge when you leave the path. <i>Performance?</i> There are faster alternatives. <i>Cutting edge?</i> uBLAS 
+is more than 10 years old and missed all new stuff from C++11. </p>
+
+<p>Q: I'm running the uBLAS dense vector and matrix benchmarks. Why do I see a significant performance difference
+between the native C and library implementations?<br />
+A: uBLAS distinguishes debug mode (size and type conformance checks enabled, expression templates disabled) and release
+mode (size and type conformance checks disabled, expression templates enabled). Please check, if the preprocessor
+symbol <code>NDEBUG</code> of <code>cassert</code> is defined. <code>NDEBUG</code> enables release mode, which in turn
+uses expression templates. You can optionally define <code>BOOST_UBLAS_NDEBUG</code> to disable all bounds, structure
+and similar checks of uBLAS.</p>
+
+<p>Q: I've written some uBLAS tests, which try to incorrectly assign different matrix types or overrun vector and
+matrix dimensions. Why don't I get a compile time or runtime diagnostic?<br />
+A: uBLAS distinguishes debug mode (size and type conformance checks enabled, expression templates disabled) and release
+mode (size and type conformance checks disabled, expression templates enabled). Please check, if the preprocessor
+symbol <code>NDEBUG</code> of <code>cassert</code> is defined. <code>NDEBUG</code> disables debug mode, which is needed
+to get size and type conformance checks.</p>
+
+<p>Q: I've written some uBLAS benchmarks to measure the performance of matrix chain multiplications like <code>prod (A,
+prod (B, C))</code> and see a significant performance penalty due to the use of expression templates. How can I disable
+expression templates?<br />
+A: You do not need to disable expression templates. Please try reintroducing temporaries using either <code>prod
+(A,</code> <code><em>matrix_type</em></code> <code>(prod (B, C)))</code> or <code>prod (A,
+prod&lt;</code><code><em>matrix_type</em></code> <code>&gt; (B, C))</code>.</p>
+
+<hr />
+
+<p>Copyright (&copy;) 2000-2011 Joerg Walter, Mathias Koch, Gunter Winkler, David Bellot<br />
+Use, modification and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file
+LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>
+).</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/iterator_concept.html b/doc/iterator_concept.html
new file mode 100644
index 0000000..c9e4c99
--- /dev/null
+++ b/doc/iterator_concept.html
@@ -0,0 +1,1168 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Iterator Concepts</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Iterator Concepts</h1>
+<div class="toc" id="toc"></div>
+<p>An Iterator is a restricted pointer-like object pointing into a
+vector or matrix container.</p>
+<h2><a name="indexed_bidirectional_iterator" 
+></a>Indexed Bidirectional Iterator</h2>
+<h4>Description</h4>
+<p>An Indexed Bidirectional Iterator is an iterator of a container
+that can be dereferenced, incremented, decremented and carries
+index information.</p>
+<h4>Refinement of</h4>
+<p>Assignable, Equality Comparable, Default Constructible.</p>
+<h4>Associated types</h4>
+<table border="1" summary="associated types">
+<tbody>
+<tr>
+<td>Value type</td>
+<td>The type of the value obtained by dereferencing a Indexed
+Bidirectional Iterator</td>
+</tr>
+<tr>
+<td>Container type</td>
+<td>The type of the container a Indexed Bidirectional Iterator
+points into.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notation</h4>
+<table border="0" summary="notation">
+<tbody>
+<tr>
+<td><code>I</code></td>
+<td>A type that is a model of Indexed Bidirectional Iterator</td>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The value type of <code>I</code></td>
+</tr>
+<tr>
+<td><code>C</code></td>
+<td>The container type of <code>I</code></td>
+</tr>
+<tr>
+<td><code>it</code>, <code>itt, it1</code>, <code>it2</code></td>
+<td>Objects of type <code>I</code></td>
+</tr>
+<tr>
+<td><code>t</code></td>
+<td>Object of type <code>T</code></td>
+</tr>
+<tr>
+<td><code>c</code></td>
+<td>Object of type <code>C</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Definitions</h4>
+<p>A Indexed Bidirectional Iterator may be <i>mutable</i>, meaning
+that the values referred to by objects of that type may be
+modified, or <i>constant</i> , meaning that they may not. If an
+iterator type is mutable, this implies that its value type is a
+model of Assignable; the converse, though, is not necessarily
+true.</p>
+<p>A Indexed Bidirectional Iterator may have a <i>singular</i>
+value, meaning that the results of most operations, including
+comparison for equality, are undefined. The only operation that is
+guaranteed to be supported is assigning a nonsingular iterator to a
+singular iterator.</p>
+<p>A Indexed Bidirectional Iterator may have a
+<i>dereferenceable</i> value, meaning that dereferencing it yields
+a well-defined value. Dereferenceable iterators are always
+nonsingular, but the converse is not true.</p>
+<p>An Indexed Bidirectional Iterator is <i>past-the-end</i> if it
+points beyond the last element of a container. Past-the-end values
+are nonsingular and nondereferenceable.</p>
+<h4>Valid expressions</h4>
+<p>In addition to the expressions defined for Assignable, Equality
+Comparable and Default Constructible, the following expressions
+must be valid.</p>
+<table border="1" summary="expressions">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Type requirements</th>
+<th>Return type</th>
+</tr>
+<tr>
+<td>Default constructor</td>
+<td><code>I it</code></td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Dereference</td>
+<td><code>*it</code></td>
+<td>&nbsp;</td>
+<td>Convertible to <code>T</code>.</td>
+</tr>
+<tr>
+<td>Dereference assignment</td>
+<td><code>*it = t</code></td>
+<td><code>I</code> is mutable.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Member access</td>
+<td><code>it-&gt;m</code></td>
+<td><code>T</code> is a type for which <code>t.m</code> is
+defined.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Preincrement</td>
+<td><code>++ it</code></td>
+<td>&nbsp;</td>
+<td><code>I &amp;</code></td>
+</tr>
+<tr>
+<td>Postincrement</td>
+<td><code>it ++</code></td>
+<td>&nbsp;</td>
+<td><code>I</code></td>
+</tr>
+<tr>
+<td>Predecrement</td>
+<td><code>-- it</code></td>
+<td>&nbsp;</td>
+<td><code>I &amp;</code></td>
+</tr>
+<tr>
+<td>Postdecrement</td>
+<td><code>it --</code></td>
+<td>&nbsp;</td>
+<td><code>I</code></td>
+</tr>
+<tr>
+<td>Index</td>
+<td><code>it.index ()</code></td>
+<td>&nbsp;</td>
+<td><code>C::size_type</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Expression Semantics</h4>
+<p>Semantics of an expression is defined only where it differs
+from, or is not defined in, Assignable, Equality Comparable and
+Default Constructible.</p>
+<table border="1" summary="semantics">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Precondition</th>
+<th>Semantics</th>
+<th>Postcondition</th>
+</tr>
+<tr>
+<td>Default constructor</td>
+<td><code>I it</code></td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+<td><code>it</code> is singular.</td>
+</tr>
+<tr>
+<td>Dereference</td>
+<td><code>*it</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Dereference assignment</td>
+<td><code>*it = t</code></td>
+<td>Same as for <code>*it</code>.</td>
+<td>&nbsp;</td>
+<td><code>*it</code> is a copy of t.</td>
+</tr>
+<tr>
+<td>Member access</td>
+<td><code>it-&gt;m</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td>Equivalent to <code>(*it).m</code></td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Preincrement</td>
+<td><code>++ it</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td><code>it</code> is modified to point to the next element.</td>
+<td><code>it</code> is dereferenceable or past-the-end.
+<code><br />
+&amp;it == &amp;++ it</code>.<br />
+If <code>it1 == it2</code>,<br />
+then <code>++ it1 == ++ it2</code>.</td>
+</tr>
+<tr>
+<td>Postincrement</td>
+<td><code>it ++</code></td>
+<td>Same as for <code>++ it</code>.</td>
+<td>Equivalent to<br />
+<code>{<br />
+&nbsp;I itt = it;<br />
+&nbsp;++ it;<br />
+&nbsp;return itt;<br />
+}</code></td>
+<td><code>it</code> is dereferenceable or past-the-end.</td>
+</tr>
+<tr>
+<td>Predecrement</td>
+<td><code>-- it</code></td>
+<td><code>it</code> is dereferenceable or past-the-end.<br />
+There exists a dereferenceable iterator <code>itt</code> such that
+<code>it == ++ itt</code>.</td>
+<td><code>it</code> is modified to point to the previous
+element.</td>
+<td><code>it</code> is dereferenceable.<br />
+<code>&amp;it = &amp;-- it</code>.<br />
+If <code>it1 == it2</code>,<br />
+then <code>-- it1 == -- it2</code>.<br />
+If <code>it2</code> is dereferenceable and <code>it1 ==
+++it2</code>,<br />
+then <code>--it1 == it2</code>.</td>
+</tr>
+<tr>
+<td>Postdecrement</td>
+<td><code>it --</code></td>
+<td>Same as for -- <code>it</code>.</td>
+<td>Equivalent to<br />
+<code>{<br />
+&nbsp;I itt = it;<br />
+&nbsp;-- it;<br />
+&nbsp;return itt;<br />
+}</code></td>
+<td><code>it</code> is dereferenceable.&nbsp;</td>
+</tr>
+<tr>
+<td>Index</td>
+<td><code>it.index ()</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td><code>it.index () &gt;= 0</code><br />
+and<br />
+<code>it.index () &lt; it ().size ()</code></td>
+<td>If <code>it1 == it2</code>,<br />
+then <code>it1.index () == it2.index ()</code>.<br />
+If <code>it1 == it2</code>,<br />
+then <code>it1.index () &lt; (++ it2).index
+()</code>.<br />
+If <code>it1 == it2</code>,<br />
+then <code>it1.index () &gt; (-- it2).index
+()</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Complexity guarantees</h4>
+<p>The complexity of operations on indexed bidirectional iterators
+is guaranteed to be amortized constant time.</p>
+<h4>Invariants</h4>
+<table border="1" summary="invariants">
+<tbody>
+<tr>
+<td>Identity</td>
+<td><code>it1 == it2</code> if and only if <code>&amp;*it1 ==
+&amp;*it2</code>.</td>
+</tr>
+<tr>
+<td>Symmetry of increment and decrement</td>
+<td>If <code>it</code> is dereferenceable, then <code>++ it;
+--it;</code> is a null operation. Similarly, <code>-- it; ++
+it;</code> is a null operation.</td>
+</tr>
+<tr>
+<td>Relation between iterator index and container element
+operator</td>
+<td>If <code>it</code> is dereferenceable, <code>*it == it ()
+(it.index ())</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Models</h4>
+<ul>
+<li><code>sparse_vector::iterator</code></li>
+</ul>
+<h2><a name="indexed_random_access_iterator"
+></a>Indexed Random Access Iterator</h2>
+<h4>Description</h4>
+<p>An Indexed Random Access Iterator is an iterator of a container
+that can be dereferenced, moved forward, moved backward and carries
+index information.</p>
+<h4>Refinement of</h4>
+<p>LessThanComparable, <a href=
+"#indexed_bidirectional_iterator">Indexed Bidirectional
+Iterator</a> .</p>
+<h4>Associated types</h4>
+<table border="1" summary="associated types">
+<tbody>
+<tr>
+<td>Value type</td>
+<td>The type of the value obtained by dereferencing a Indexed
+Random Access Iterator</td>
+</tr>
+<tr>
+<td>Container type</td>
+<td>The type of the container a Indexed Random Access Iterator
+points into.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notation</h4>
+<table border="0" summary="notation">
+<tbody>
+<tr>
+<td><code>I</code></td>
+<td>A type that is a model of Indexed Random Access Iterator</td>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The value type of <code>I</code></td>
+</tr>
+<tr>
+<td><code>C</code></td>
+<td>The container type of <code>I</code></td>
+</tr>
+<tr>
+<td><code>it</code>, <code>itt, it1</code>, <code>it2</code></td>
+<td>Objects of type <code>I</code></td>
+</tr>
+<tr>
+<td><code>t</code></td>
+<td>Object of type <code>T</code></td>
+</tr>
+<tr>
+<td><code>n</code></td>
+<td>Object of type <code>C::difference_type</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Definitions</h4>
+<p>An Indexed Random Access Iterator <code>it1</code> is
+<i>reachable</i> from an Indexed Random Access Iterator
+<code>it2</code> if, after applying <code>operator ++</code> to
+<code>it2</code> a finite number of times, <code>it1 ==
+it2</code>.</p>
+<h4>Valid expressions</h4>
+<p>In addition to the expressions defined for <a href=
+"#indexed_bidirectional_iterator">Indexed Bidirectional
+Iterator</a> , the following expressions must be valid.</p>
+<table border="1" summary="expressions">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Type requirements</th>
+<th>Return type</th>
+</tr>
+<tr>
+<td>Forward motion</td>
+<td><code>it += n</code></td>
+<td>&nbsp;</td>
+<td><code>I &amp;</code></td>
+</tr>
+<tr>
+<td>Iterator addition</td>
+<td><code>it + n</code></td>
+<td>&nbsp;</td>
+<td><code>I</code></td>
+</tr>
+<tr>
+<td>Backward motion</td>
+<td><code>i -= n</code></td>
+<td>&nbsp;</td>
+<td><code>I &amp;</code></td>
+</tr>
+<tr>
+<td>Iterator subtraction</td>
+<td><code>it - n</code></td>
+<td>&nbsp;</td>
+<td><code>I</code>&nbsp;</td>
+</tr>
+<tr>
+<td>Difference</td>
+<td><code>it1 - it2</code></td>
+<td>&nbsp;</td>
+<td><code>C::difference_type</code></td>
+</tr>
+<tr>
+<td>Element operator</td>
+<td><code>it [n]</code></td>
+<td>&nbsp;</td>
+<td>Convertible to <code>T</code>.</td>
+</tr>
+<tr>
+<td>Element assignment</td>
+<td><code>it [n] = t</code></td>
+<td><code>I</code> is mutable</td>
+<td>Convertible to <code>T</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Expression Semantics</h4>
+<p>Semantics of an expression is defined only where it differs
+from, or is not defined in, <a href=
+"#indexed_bidirectional_iterator">Indexed Bidirectional
+Iterator</a> .</p>
+<table border="1" summary="semantics">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Precondition</th>
+<th>Semantics</th>
+<th>Postcondition</th>
+</tr>
+<tr>
+<td>Forward motion</td>
+<td><code>it += n</code></td>
+<td>Including <code>it</code> itself, there must be <code>n</code>
+dereferenceable or past-the-end iterators following or preceding
+<code>it</code>, depending on whether <code>n</code> is positive or
+negative.</td>
+<td>If <code>n &gt; 0</code>, equivalent to executing <code>++
+it</code> <code>n</code> times. If <code>n &lt; 0</code>,
+equivalent to executing <code>-- it</code> <code>n</code> times. If
+<code>n == 0</code>, this is a null operation.</td>
+<td><code>it</code> is dereferenceable or past-the-end.</td>
+</tr>
+<tr>
+<td>Iterator addition</td>
+<td><code>it + n</code></td>
+<td>Same as for <code>i += n</code>.</td>
+<td>Equivalent to<br />
+<code>{<br />
+&nbsp;I itt = it;<br />
+&nbsp;return itt += n;<br />
+}</code></td>
+<td>Result is dereferenceable or past-the-end.</td>
+</tr>
+<tr>
+<td>Backward motion</td>
+<td><code>it -= n</code></td>
+<td>Including <code>it</code> itself, there must be <code>n</code>
+dereferenceable or past-the-end iterators preceding or following
+<code>it</code>, depending on whether <code>n</code> is positive or
+negative.</td>
+<td>Equivalent to <code>it += (-n)</code>.</td>
+<td><code>it</code> is dereferenceable or past-the-end.</td>
+</tr>
+<tr>
+<td>Iterator subtraction</td>
+<td><code>it - n</code></td>
+<td>Same as for <code>i -= n</code>.</td>
+<td>Equivalent to<br />
+<code>{<br />
+&nbsp;I itt = it;<br />
+&nbsp;return itt -= n;<br />
+}</code></td>
+<td>Result is dereferenceable or past-the-end.</td>
+</tr>
+<tr>
+<td>Difference</td>
+<td><code>it1 - it2</code></td>
+<td>Either <code>it1</code> is reachable from <code>it2</code> or
+<code>it2</code> is reachable from <code>it1</code>, or both.</td>
+<td>Returns a number <code>n</code> such that <code>it1 == it2 +
+n</code></td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Element operator</td>
+<td><code>it [n]</code></td>
+<td><code>it + n</code> exists and is dereferenceable.</td>
+<td>Equivalent to <code>*(it + n)</code></td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Element assignment</td>
+<td><code>i[n] = t</code></td>
+<td>Same as for <code>it [n]</code>.</td>
+<td>Equivalent to <code>*(it + n) = t</code></td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Complexity guarantees</h4>
+<p>The complexity of operations on indexed random access iterators
+is guaranteed to be amortized constant time.</p>
+<h4>Invariants</h4>
+<table border="1" summary="invariants">
+<tbody>
+<tr>
+<td>Symmetry of addition and subtraction</td>
+<td>If <code>it + n</code> is well-defined, then <code>it += n; it
+-= n;</code> and <code>(it + n) - n</code> are null operations.
+Similarly, if <code>it - n</code> is well-defined, then <code>it -=
+n; it += n;</code> and <code>(it - n) + n</code> are null
+operations.</td>
+</tr>
+<tr>
+<td>Relation between distance and addition</td>
+<td>If <code>it1 - it2</code> is well-defined, then <code>it1 ==
+it2 + (it1 - it2)</code>.</td>
+</tr>
+<tr>
+<td>Reachability and distance</td>
+<td>If <code>it1</code> is reachable from <code>it2</code>, then
+<code>it1 - it2 &gt;= 0</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Models</h4>
+<ul>
+<li><code>vector::iterator</code></li>
+</ul>
+<h2><a name="indexed_bidirectional_cr_iterator"
+></a>Indexed Bidirectional Column/Row Iterator</h2>
+<h4>Description</h4>
+<p>An Indexed Bidirectional Column/Row Iterator is an iterator of a
+container that can be dereferenced, incremented, decremented and
+carries index information.</p>
+<h4>Refinement of</h4>
+<p>Assignable, Equality Comparable, Default Constructible.</p>
+<h4>Associated types</h4>
+<table border="1" summary="associated types">
+<tbody>
+<tr>
+<td>Value type</td>
+<td>The type of the value obtained by dereferencing a Indexed
+Bidirectional Column/Row Iterator</td>
+</tr>
+<tr>
+<td>Container type</td>
+<td>The type of the container a Indexed Bidirectional Column/Row
+Iterator points into.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notation</h4>
+<table border="0" summary="notation">
+<tbody>
+<tr>
+<td><code>I1</code></td>
+<td>A type that is a model of Indexed Bidirectional Column/Row
+Iterator</td>
+</tr>
+<tr>
+<td><code>I2</code></td>
+<td>A type that is a model of Indexed Bidirectional Row/Column
+Iterator</td>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The value type of <code>I1</code> and <code>I2</code></td>
+</tr>
+<tr>
+<td><code>C</code></td>
+<td>The container type of <code>I1</code> and <code>I2</code></td>
+</tr>
+<tr>
+<td><code>it1</code>, <code>it1t, it11</code>,
+<code>it12</code></td>
+<td>Objects of type <code>I1</code></td>
+</tr>
+<tr>
+<td><code>it2</code>, <code>it2t</code></td>
+<td>Objects of type <code>I2</code></td>
+</tr>
+<tr>
+<td><code>t</code></td>
+<td>Object of type <code>T</code></td>
+</tr>
+<tr>
+<td><code>c</code></td>
+<td>Object of type <code>C</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Definitions</h4>
+<h4>Valid expressions</h4>
+<p>In addition to the expressions defined for Assignable, Equality
+Comparable and Default Constructible, the following expressions
+must be valid.</p>
+<table border="1" summary="expressions">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Type requirements</th>
+<th>Return type</th>
+</tr>
+<tr>
+<td>Default constructor</td>
+<td><code>I1 it</code></td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Dereference</td>
+<td><code>*it</code></td>
+<td>&nbsp;</td>
+<td>Convertible to <code>T</code>.</td>
+</tr>
+<tr>
+<td>Dereference assignment</td>
+<td><code>*it = t</code></td>
+<td><code>I1</code> is mutable.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Member access</td>
+<td><code>it-&gt;m</code></td>
+<td><code>T</code> is a type for which <code>t.m</code> is
+defined.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Preincrement</td>
+<td><code>++ it</code></td>
+<td>&nbsp;</td>
+<td><code>I1 &amp;</code></td>
+</tr>
+<tr>
+<td>Postincrement</td>
+<td><code>it ++</code></td>
+<td>&nbsp;</td>
+<td><code>I1</code></td>
+</tr>
+<tr>
+<td>Predecrement</td>
+<td><code>-- it</code></td>
+<td>&nbsp;</td>
+<td><code>I1 &amp;</code></td>
+</tr>
+<tr>
+<td>Postdecrement</td>
+<td><code>it --</code></td>
+<td>&nbsp;</td>
+<td><code>I1</code></td>
+</tr>
+<tr>
+<td>Row Index</td>
+<td><code>it.index1 ()</code></td>
+<td>&nbsp;</td>
+<td><code>C::size_type</code></td>
+</tr>
+<tr>
+<td>Column Index</td>
+<td><code>it.index2 ()</code></td>
+<td>&nbsp;</td>
+<td><code>C::size_type</code></td>
+</tr>
+<tr>
+<td>Row/Column Begin</td>
+<td><code>it.begin ()</code></td>
+<td>&nbsp;</td>
+<td><code>I2</code></td>
+</tr>
+<tr>
+<td>Row/Column End</td>
+<td><code>it.end ()</code></td>
+<td>&nbsp;</td>
+<td><code>I2</code></td>
+</tr>
+<tr>
+<td>Reverse Row/Column Begin</td>
+<td><code>it.rbegin ()</code></td>
+<td>&nbsp;</td>
+<td><code>reverse_iterator&lt;I2&gt;</code></td>
+</tr>
+<tr>
+<td>Reverse Row/Column End</td>
+<td><code>it.rend ()</code></td>
+<td>&nbsp;</td>
+<td><code>reverse_iterator&lt;I2&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Expression Semantics</h4>
+<p>Semantics of an expression is defined only where it differs
+from, or is not defined in, Assignable, Equality Comparable and
+Default Constructible.</p>
+<table border="1" summary="semantics">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Precondition</th>
+<th>Semantics</th>
+<th>Postcondition</th>
+</tr>
+<tr>
+<td>Default constructor</td>
+<td><code>I1 it</code></td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+<td><code>it</code> is singular.</td>
+</tr>
+<tr>
+<td>Dereference</td>
+<td><code>*it</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td>&nbsp;</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Dereference assignment</td>
+<td><code>*it = t</code></td>
+<td>Same as for <code>*it</code>.</td>
+<td>&nbsp;</td>
+<td><code>*it</code> is a copy of t.</td>
+</tr>
+<tr>
+<td>Member access</td>
+<td><code>it-&gt;m</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td>Equivalent to <code>(*it).m</code></td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Preincrement</td>
+<td><code>++ it</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td><code>it</code> is modified to point to the next element of
+the column/row, i.e. for column iterators holds<br />
+<code>it.index1 () &lt; (++ it).index1 ()</code> and<br />
+<code>it.index2 () == (++ it).index2 ()</code>,<br />
+for row iterators holds<br />
+<code>it.index1 () == (++ it).index1 ()</code> and<br />
+<code>it.index2 () &lt; (++ it).index2 ()</code>.<br /></td>
+<td><code>it</code> is dereferenceable or past-the-end.
+<code><br />
+&amp;it == &amp;++ it</code>.<br />
+If <code>it1 == it2</code>,<br />
+then <code>++ it1 == ++ it2</code>.</td>
+</tr>
+<tr>
+<td>Postincrement</td>
+<td><code>it ++</code></td>
+<td>Same as for <code>++ it</code>.</td>
+<td>Equivalent to<br />
+<code>{<br />
+&nbsp;I1 itt = it;<br />
+&nbsp;++ it;<br />
+&nbsp;return itt;<br />
+}</code></td>
+<td><code>it</code> is dereferenceable or past-the-end.</td>
+</tr>
+<tr>
+<td>Predecrement</td>
+<td><code>-- it</code></td>
+<td><code>it</code> is dereferenceable or past-the-end.<br />
+There exists a dereferenceable iterator <code>itt</code> such that
+<code>it == ++ itt</code>.</td>
+<td><code>it</code> is modified to point to the previous&nbsp;
+element of the column/row, i.e. for column iterators holds<br />
+<code>it.index1 () &gt; (-- it).index1 ()</code> and<br />
+<code>it.index2 () == (-- it).index2 ()</code>,<br />
+for row iterators holds<br />
+<code>it.index1 () == (-- it).index1 ()</code> and<br />
+<code>it.index2 () &gt; (-- it).index2 ()</code>.</td>
+<td><code>it</code> is dereferenceable.<br />
+<code>&amp;it = &amp;-- it</code>.<br />
+If <code>it1 == it2</code>,<br />
+then <code>-- it1 == -- it2</code>.</td>
+</tr>
+<tr>
+<td>Postdecrement</td>
+<td><code>it --</code></td>
+<td>Same as for -- <code>it</code>.</td>
+<td>Equivalent to<br />
+<code>{<br />
+&nbsp;I1 itt = it;<br />
+&nbsp;-- it;<br />
+&nbsp;return itt;<br />
+}</code></td>
+<td><code>it</code> is dereferenceable.&nbsp;</td>
+</tr>
+<tr>
+<td>Row Index</td>
+<td><code>it.index1 ()</code></td>
+<td>If <code>it</code> is a Row iterator then <code>it</code> must be dereferenceable.</td>
+<td><code>it.index1 () &gt;= 0</code> and<br />
+<code>it.index1 () &lt; it () .size1 ()</code></td>
+<td>If <code>it1 == it2</code>,<br />
+then <code>it1.index1 () == 12.index1 ()</code>.<br />
+If <code>it1</code>, <code>it2</code> are Row Iterators with <code>it1 == it2</code>,<br />
+then <code>it1.index1 () &lt; (++ it2</code>).<code>index1 ()</code>.<br />
+and <code>it1.index1 () &gt; (-- it2</code>).<code>index1 ()</code>.</td>
+</tr>
+<tr>
+<td>Column Index</td>
+<td><code>it.index2 ()</code></td>
+<td>If <code>it</code> is a Column iterator then <code>it</code> must be dereferenceable.</td>
+<td><code>it.index2 () &gt;= 0</code> and<br />
+<code>it.index2 () &lt; it () .size2 ()</code></td>
+<td>If <code>it1 == it2</code>,<br />
+then <code>it1.index2 () == it2</code>.<code>index2 ()</code>
+.<br />
+If <code>it1</code>, <code>it2</code> are Column Iterators with <code>it1 == i12</code>,<br />
+then <code>it1.index2 () &lt; (++ it2</code>).<code>index2 ()</code>.<br />
+end <code>it1.index2 () &gt; (-- it2</code>).<code>index2 ()</code>.</td>
+</tr>
+<tr>
+<td>Row/Column Begin</td>
+<td><code>it.begin ()</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td>If <code>it</code> is a Column Iterator,<br />
+then <code>it2 = it.begin ()</code> is a Row Iterator<br />
+with <code>it2.index1 () == it.index1 ()</code>.
+<p>If <code>it</code> is a Row Iterator,<br />
+then <code>it2 = it.begin ()</code> is a Column Iterator<br />
+with <code>it2.index2 () == it.index2 ()</code>.</p>
+</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Row/Column End</td>
+<td><code>it.end ()</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td>If <code>it</code> is a Column Iterator,<br />
+then <code>it2 = it.end ()</code> is a Row Iterator<br />
+with <code>it2.index1 () == it.index1 ()</code>.
+<p>If <code>it</code> is a Row Iterator,<br />
+then <code>it2 = it.end ()</code> is a Column Iterator<br />
+with <code>it2.index2 () == it.index2 ()</code>.</p>
+</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Reverse Row/Column Begin</td>
+<td><code>it.rbegin ()</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td>Equivalent to <code>reverse_iterator&lt;I2&gt; (it.end
+())</code>.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Reverse Row/Column End</td>
+<td><code>it.rend ()</code></td>
+<td><code>it</code> is dereferenceable.</td>
+<td>Equivalent to <code>reverse_iterator&lt;I2&gt; (it.begin
+())</code>.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Complexity guarantees</h4>
+<p>The complexity of operations on indexed bidirectional column/row
+iterators is guaranteed to be logarithmic depending on the size of
+the container. The complexity of one iterator (depending on the
+storage layout) can be lifted to be amortized constant time. The
+complexity of the other iterator (depending on the storage layout
+and the container) can be lifted to be amortized constant time for
+the first row/first column respectively.</p>
+<h4>Invariants</h4>
+<table border="1" summary="invariants">
+<tbody>
+<tr>
+<td>Identity</td>
+<td><code>it1 == it2</code> if and only if <code>&amp;*it1 ==
+&amp;*it2</code>.</td>
+</tr>
+<tr>
+<td>Symmetry of increment and decrement</td>
+<td>If <code>it</code> is dereferenceable, then <code>++ it;
+--it;</code> is a null operation. Similarly, <code>-- it; ++
+it;</code> is a null operation.</td>
+</tr>
+<tr>
+<td>Relation between iterator index and container element
+operator</td>
+<td>If <code>it</code> is dereferenceable, <code>*it == it ()
+(it.index1 (), it.index2 ())</code></td>
+</tr>
+<tr>
+<td>Relation between iterator column/row begin and iterator
+index</td>
+<td>If <code>it</code> is a Column Iterator
+and <code>it2 = it.begin ()</code> then <code>it2.index2 () &lt;
+it2t.index2 ()</code> for all <code>it2t</code> with <code>it2t ()
+== it2 ()</code> and <code>it2t ().index1 () == it2 ().index1
+()</code>.
+<p>If <code>it</code> is a Row Iterator and
+<code>it2 = it.begin ()</code> then <code>it2.index1 () &lt;
+it2t.index1 ()</code> for all <code>it2t</code> with <code>it2t ()
+== it2 ()</code> and <code>it2t ().index2 () == it2 ().index2
+()</code>.</p>
+</td>
+</tr>
+<tr>
+<td>Relation between iterator column/row end and iterator
+index</td>
+<td>If <code>it</code> is a Column Iterator
+and <code>it2 = it.end ()</code> then <code>it2.index2 () &gt;
+it2t.index2 ()</code> for all <code>it2t</code> with <code>it2t ()
+== it2 ()</code> and <code>it2t ().index1 () == it2 ().index1
+()</code>.
+<p>If <code>it</code> is a Row Iterator and
+<code>it2 = it.end ()</code> then <code>it2.index1 () &gt;
+it2t.index1 ()</code> for all <code>it2t</code> with <code>it2t ()
+== it2 ()</code> and <code>it2t ().index2 () == it2 ().index2
+()</code>.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<h4>Models</h4>
+<ul>
+<li><code>sparse_matrix::iterator1</code></li>
+<li><code>sparse_matrix::iterator2</code></li>
+</ul>
+<h2><a name="indexed_random_access_cr_iterator"
+></a>Indexed Random Access Column/Row Iterator</h2>
+<h4>Description</h4>
+<p>An Indexed Random Access Column/Row Iterator is an iterator of a
+container that can be dereferenced, incremented, decremented and
+carries index information.</p>
+<h4>Refinement of</h4>
+<p><a href="#indexed_bidirectional_cr_iterator">Indexed
+Bidirectional Column/Row Iterator</a> .</p>
+<h4>Associated types</h4>
+<table border="1" summary="associated types">
+<tbody>
+<tr>
+<td>Value type</td>
+<td>The type of the value obtained by dereferencing a Indexed
+Random Access Column/Row Iterator</td>
+</tr>
+<tr>
+<td>Container type</td>
+<td>The type of the container a Indexed Random Access Column/Row
+Iterator points into.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notation</h4>
+<table border="0" summary="notation">
+<tbody>
+<tr>
+<td><code>I</code></td>
+<td>A type that is a model of Indexed Random Access Column/Row
+Iterator</td>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The value type of <code>I</code></td>
+</tr>
+<tr>
+<td><code>C</code></td>
+<td>The container type of <code>I</code></td>
+</tr>
+<tr>
+<td><code>it</code>, <code>itt, it1</code>, <code>it2</code></td>
+<td>Objects of type <code>I</code></td>
+</tr>
+<tr>
+<td><code>t</code></td>
+<td>Object of type <code>T</code></td>
+</tr>
+<tr>
+<td><code>c</code></td>
+<td>Object of type <code>C</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Definitions</h4>
+<h4>Valid expressions</h4>
+<p>In addition to the expressions defined for <a href=
+"#indexed_bidirectional_cr_iterator">Indexed Bidirectional
+Column/Row Iterator</a> , the following expressions must be
+valid.</p>
+<table border="1" summary="expressions">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Type requirements</th>
+<th>Return type</th>
+</tr>
+<tr>
+<td>Forward motion</td>
+<td><code>it += n</code></td>
+<td>&nbsp;</td>
+<td><code>I &amp;</code></td>
+</tr>
+<tr>
+<td>Iterator addition</td>
+<td><code>it + n</code></td>
+<td>&nbsp;</td>
+<td><code>I</code></td>
+</tr>
+<tr>
+<td>Backward motion</td>
+<td><code>i -= n</code></td>
+<td>&nbsp;</td>
+<td><code>I &amp;</code></td>
+</tr>
+<tr>
+<td>Iterator subtraction</td>
+<td><code>it - n</code></td>
+<td>&nbsp;</td>
+<td><code>I</code>&nbsp;</td>
+</tr>
+<tr>
+<td>Difference</td>
+<td><code>it1 - it2</code></td>
+<td>&nbsp;</td>
+<td><code>C::difference_type</code></td>
+</tr>
+<tr>
+<td>Element operator</td>
+<td><code>it [n]</code></td>
+<td>&nbsp;</td>
+<td>Convertible to <code>T</code>.</td>
+</tr>
+<tr>
+<td>Element assignment</td>
+<td><code>it [n] = t</code></td>
+<td><code>I</code> is mutable</td>
+<td>Convertible to <code>T</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Expression Semantics</h4>
+<p>Semantics of an expression is defined only where it differs
+from, or is not defined in, <a href=
+"#indexed_bidirectional_cr_iterator">Indexed Bidirectional
+Column/Row Iterator</a> .</p>
+<table border="1" summary="semantics">
+<tbody>
+<tr>
+<th>Name</th>
+<th>Expression</th>
+<th>Precondition</th>
+<th>Semantics</th>
+<th>Postcondition</th>
+</tr>
+<tr>
+<td>Forward motion</td>
+<td><code>it += n</code></td>
+<td>Including <code>it</code> itself, there must be <code>n</code>
+dereferenceable or past-the-end iterators following or preceding
+<code>it</code>, depending on whether <code>n</code> is positive or
+negative.</td>
+<td>If <code>n &gt; 0</code>, equivalent to executing <code>++
+it</code> <code>n</code> times. If <code>n &lt; 0</code>,
+equivalent to executing <code>-- it</code> <code>n</code> times. If
+<code>n == 0</code>, this is a null operation.</td>
+<td><code>it</code> is dereferenceable or past-the-end.</td>
+</tr>
+<tr>
+<td>Iterator addition</td>
+<td><code>it + n</code></td>
+<td>Same as for <code>i += n</code>.</td>
+<td>Equivalent to<br />
+<code>{<br />
+&nbsp;I itt = it;<br />
+&nbsp;return itt += n;<br />
+}</code></td>
+<td>Result is dereferenceable or past-the-end.</td>
+</tr>
+<tr>
+<td>Backward motion</td>
+<td><code>it -= n</code></td>
+<td>Including <code>it</code> itself, there must be <code>n</code>
+dereferenceable or past-the-end iterators preceding or following
+<code>it</code>, depending on whether <code>n</code> is positive or
+negative.</td>
+<td>Equivalent to <code>it += (-n)</code>.</td>
+<td><code>it</code> is dereferenceable or past-the-end.</td>
+</tr>
+<tr>
+<td>Iterator subtraction</td>
+<td><code>it - n</code></td>
+<td>Same as for <code>i -= n</code>.</td>
+<td>Equivalent to<br />
+<code>{<br />
+&nbsp;I itt = it;<br />
+&nbsp;return itt -= n;<br />
+}</code></td>
+<td>Result is dereferenceable or past-the-end.</td>
+</tr>
+<tr>
+<td>Difference</td>
+<td><code>it1 - it2</code></td>
+<td>Either <code>it1</code> is reachable from <code>it2</code> or
+<code>it2</code> is reachable from <code>it1</code>, or both.</td>
+<td>Returns a number <code>n</code> such that <code>it1 == it2 +
+n</code></td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Element operator</td>
+<td><code>it [n]</code></td>
+<td><code>it + n</code> exists and is dereferenceable.</td>
+<td>Equivalent to <code>*(it + n)</code></td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td>Element assignment</td>
+<td><code>i[n] = t</code></td>
+<td>Same as for <code>it [n]</code>.</td>
+<td>Equivalent to <code>*(it + n) = t</code></td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Complexity guarantees</h4>
+<p>The complexity of operations on indexed random access Column/Row
+iterators is guaranteed to be amortized constant time.</p>
+<h4>Invariants</h4>
+<table border="1" summary="invariants">
+<tbody>
+<tr>
+<td>Symmetry of addition and subtraction</td>
+<td>If <code>it + n</code> is well-defined, then <code>it += n; it
+-= n;</code> and <code>(it + n) - n</code> are null operations.
+Similarly, if <code>it - n</code> is well-defined, then <code>it -=
+n; it += n;</code> and <code>(it - n) + n</code> are null
+operations.</td>
+</tr>
+<tr>
+<td>Relation between distance and addition</td>
+<td>If <code>it1 - it2</code> is well-defined, then <code>it1 ==
+it2 + (it1 - it2)</code>.</td>
+</tr>
+<tr>
+<td>Reachability and distance</td>
+<td>If <code>it1</code> is reachable from <code>it2</code>, then
+<code>it1 - it2 &gt;= 0</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Models</h4>
+<ul>
+<li><code>matrix::iterator1</code></li>
+<li><code>matrix::iterator2</code></li>
+</ul>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/js/jquery-1.3.2.min.js b/doc/js/jquery-1.3.2.min.js
new file mode 100644
index 0000000..b1ae21d
--- /dev/null
+++ b/doc/js/jquery-1.3.2.min.js
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML='   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();
\ No newline at end of file
diff --git a/doc/js/jquery.toc-gw.js b/doc/js/jquery.toc-gw.js
new file mode 100644
index 0000000..d48dd4b
--- /dev/null
+++ b/doc/js/jquery.toc-gw.js
@@ -0,0 +1,166 @@
+/*!
+ * jQuery TOC Plugin v1.1.x based on 
+ * samaxesJS JavaScript Library
+ * http://code.google.com/p/samaxesjs/
+ *
+ * Copyright (c) 2008 samaxes.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * 2009-10-04, guwi17: modified and extended to meet uBLAS' needs
+ */
+
+(function($) {
+    /*
+     * The TOC plugin dynamically builds a table of contents from the headings in
+     * a document and prepends legal-style section numbers to each of the headings.
+     */
+    $.fn.toc = function(options) {
+        var opts = $.extend({}, $.fn.toc.defaults, options);
+
+        return this.each(function() {
+            var toc = $(this).append('<ul></ul>').children('ul');
+            var headers = {h1: 0, h2: 0, h3: 0, h4: 0, h5: 0, h6: 0};
+            var index = 0;
+            var indexes = {
+                    h1: (opts.exclude.match('h1') == null && $('h1').length > 0) ? ++index : 0,
+                    h2: (opts.exclude.match('h2') == null && $('h2').length > 0) ? ++index : 0,
+                    h3: (opts.exclude.match('h3') == null && $('h3').length > 0) ? ++index : 0,
+                    h4: (opts.exclude.match('h4') == null && $('h4').length > 0) ? ++index : 0,
+                    h5: (opts.exclude.match('h5') == null && $('h5').length > 0) ? ++index : 0,
+                    h6: (opts.exclude.match('h6') == null && $('h6').length > 0) ? ++index : 0
+            };
+
+            $(':header').not(opts.exclude).each(function() {
+                var linkId = "";
+                if ($(this).is('h6')) {
+                    checkContainer(headers.h6, toc);
+                    updateNumeration(headers, 'h6');
+                    $(this).text(addNumeration(headers, 'h6', $(this).text()));
+                    linkId = fixAnchor($(this));
+                    appendToTOC(toc, indexes.h6, linkId, $(this).text(), headers);
+                } else if ($(this).is('h5')) {
+                    checkContainer(headers.h5, toc);
+                    updateNumeration(headers, 'h5');
+                    $(this).text(addNumeration(headers, 'h5', $(this).text()));
+                    linkId = fixAnchor($(this));
+                    appendToTOC(toc, indexes.h5, linkId, $(this).text(), headers);
+                } else if ($(this).is('h4')) {
+                    checkContainer(headers.h4, toc);
+                    updateNumeration(headers, 'h4');
+                    $(this).text(addNumeration(headers, 'h4', $(this).text()));
+                    linkId = fixAnchor($(this));
+                    appendToTOC(toc, indexes.h4, linkId, $(this).text(), headers);
+                } else if ($(this).is('h3')) {
+                    checkContainer(headers.h3, toc);
+                    updateNumeration(headers, 'h3');
+                    $(this).text(addNumeration(headers, 'h3', $(this).text()));
+                    linkId = fixAnchor($(this));
+                    appendToTOC(toc, indexes.h3, linkId, $(this).text(), headers);
+                } else if ($(this).is('h2')) {
+                    checkContainer(headers.h2, toc);
+                    updateNumeration(headers, 'h2');
+                    $(this).text(addNumeration(headers, 'h2', $(this).text()));
+                    linkId = fixAnchor($(this));
+                    appendToTOC(toc, indexes.h2, linkId, $(this).text(), headers);
+                } else if ($(this).is('h1')) {
+                    updateNumeration(headers, 'h1');
+                    $(this).text(addNumeration(headers, 'h1', $(this).text()));
+                    linkId = fixAnchor($(this));
+                    appendToTOC(toc, indexes.h1, linkId, $(this).text(), headers);
+                }
+            });
+        });
+    };
+
+    /*
+     * Checks if the last node is an 'ul' element.
+     * If not, a new one is created.
+     */
+    function checkContainer(header, toc) {
+        if (header == 0 && !toc.find(':last').is('ul')) {
+            toc.find('li:last').append('<ul></ul>');
+        }
+    };
+
+    /*
+     * Updates headers numeration.
+     */
+    function updateNumeration(headers, header) {
+        $.each(headers, function(i, val) {
+            if (i == header)  {
+                ++headers[i];
+            } else if (i > header) {
+                headers[i] = 0;
+            }
+        });
+    };
+
+    /*
+     * Prepends the numeration to a heading.
+     */
+    function addNumeration(headers, header, text) {
+        var numeration = '';
+
+        $.each(headers, function(i, val) {
+            if (i <= header && headers[i] > 0)  {
+                numeration += headers[i] + '.';
+            }
+        });
+
+        return removeFinalDot(numeration) + ' ' + text;
+    };
+
+    function removeFinalDot(text) {
+        return (text||"").replace(/\.$/g, "" )
+    }
+
+    function fixAnchor(element) {
+        // use existing id by default
+        var linkId = element.attr('id');
+        // next, look for an anchor and use its id or name
+        if ( !linkId ) {
+            element.find('> a:first').each( function() {
+                linkId = $(this).attr('id') || $(this).attr('name');
+            });
+        }
+        // next, use the text content as last resort
+        if ( !linkId ) {
+            linkId = (element.text()||"unknown").replace(/[^a-zA-Z0-9]/g,"");
+        }
+
+        element.attr('id',linkId);
+        return linkId;
+    }
+    
+    /*
+     * Appends a new node to the TOC.
+     */
+    function appendToTOC(toc, index, id, text, headers) {
+        var parent = toc;
+
+        for (var i = 1; i < index; i++) {
+            if (parent.find('> li:last > ul').length == 0) {
+                parent = parent.append('<li><ul></ul></li>');
+            }
+            parent = parent.find('> li:last > ul');
+        }
+        if (id) {
+            parent.append('<li><a href="#' + id + '">' + text + '</a></li>');
+        } else {
+            parent.append('<li>' + text + '</li>');
+        }
+    };
+
+    $.fn.toc.defaults = {exclude: 'h1, h5, h6'}
+})(jQuery);
diff --git a/doc/matrix.html b/doc/matrix.html
new file mode 100644
index 0000000..0342d04
--- /dev/null
+++ b/doc/matrix.html
@@ -0,0 +1,768 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Matrix</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Matrix</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="matrix"></a>Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>matrix&lt;T, F, A&gt;</code> is the
+base container adaptor for dense matrices. For a <em>(m x
+n</em>)-dimensional matrix and <em>0 &lt;= i &lt; m</em>, <em>0
+&lt;= j &lt; n</em> every element <em>m</em><sub><em>i,
+j</em></sub> is mapped to the <em>(i x n + j)-</em>th element of
+the container for row major orientation or the <em>(i + j x
+m)-</em>th element of the container for column major
+orientation.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+    std::cout &lt;&lt; m &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>Functor describing the storage organization. <a href=
+"#matrix_1">[1]</a></td>
+<td><code>row_major</code></td>
+</tr>
+<tr>
+<td><code>A</code></td>
+<td>The type of the <a href="storage_concept.html">Storage</a> array. <a href="#matrix_2">[2]</a></td>
+<td><code>unbounded_array&lt;T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;matrix&lt;T, F, A&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix ()</code></td>
+<td>Allocates an uninitialized <code>matrix</code> that holds zero
+rows of zero elements.</td>
+</tr>
+<tr>
+<td><code>matrix (size_type size1, size_type size2)</code></td>
+<td>Allocates an uninitialized <code>matrix</code> that holds
+<code>size1</code> rows of <code>size2</code> elements.</td>
+</tr>
+<tr>
+<td><code>matrix (const matrix &amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix (const matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size1, size_type size2, bool
+preserve = true)</code></td>
+<td>Reallocates a <code>matrix</code> to hold <code>size1</code>
+rows of <code>size2</code> elements. The existing elements of the
+<code>matrix</code> are preseved when specified.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const array_type&amp; data () const</code></td>
+<td></td>
+</tr>
+<tr>
+<td><code>array_type&amp; data ()</code></td>
+<td></td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns a <code>const</code> reference of the <code>j</code>
+-th element in the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>matrix &amp;operator = (const matrix &amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>matrix &amp;assign_temporary (matrix &amp;m)</code></td>
+<td>Assigns a temporary. May change the matrix <code>m</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix &amp;operator = (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the matrix. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix &amp;operator += (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix &amp;plus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a matrix expression to the matrix. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix &amp;operator -= (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix &amp;minus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a matrix expression from the matrix. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the matrix with a
+scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the matrix through a
+scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (matrix &amp;m)</code></td>
+<td>Swaps the contents of the matrices.</td>
+</tr>
+<tr>
+<td><code>void insert_element (size_type i, size_type j, const_reference
+t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>j</code>-th
+element of the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void erase_element (size_type i, size_type j)</code></td>
+<td>Erases the value at the <code>j</code>-th element of the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the matrix.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="matrix_1">[1]</a> Supported parameters
+for the storage organization are <code>row_major</code> and
+<code>column_major</code>.</p>
+<p><a name="matrix_2">[2]</a> Common parameters
+for the storage array are <code>unbounded_array&lt;T&gt;</code> ,
+<code>bounded_array&lt;T&gt;</code> and
+<code>std::vector&lt;T&gt;</code> .</p>
+<h2><a name="identity_matrix"></a>Identity Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>identity_matrix&lt;T, ALLOC&gt;</code>
+represents identity matrices. For a <em>(m x n</em>)-dimensional
+identity matrix and <em>0 &lt;= i &lt; m</em>, <em>0 &lt;= j &lt;
+n</em> holds <em>id</em><sub><em>i, j</em></sub> <em>= 0</em>, if
+<em>i &lt;&gt; j</em>, and <em>id</em><sub><em>i, i</em></sub><em>=
+1</em>.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    identity_matrix&lt;double&gt; m (3);
+    std::cout &lt;&lt; m &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the matrix.</td>
+<td><code>int</code></td>
+</tr>
+<tr>
+<td><code>ALLOC</code></td>
+<td>An STL Allocator for size_type and difference_type.</td>
+<td>std::allocator</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of
+<a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;identity_matrix&lt;T&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>identity_matrix ()</code></td>
+<td>Constructs an <code>identity_matrix</code> that holds zero rows
+of zero elements.</td>
+</tr>
+<tr>
+<td><code>identity_matrix (size_type size)</code></td>
+<td>Constructs an <code>identity_matrix</code> that holds
+<code>size</code> rows of <code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>identity_matrix (const identity_matrix
+&amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, bool preserve =
+true)</code></td>
+<td>Resizes a <code>identity_matrix</code> to hold
+<code>size</code> rows of <code>size</code> elements. Therefore the
+existing elements of the <code>itendity_matrix</code> are always
+preseved.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>identity_matrix &amp;operator = (const identity_matrix
+&amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>identity_matrix &amp;assign_temporary (identity_matrix
+&amp;m)</code></td>
+<td>Assigns a temporary. May change the identity matrix
+<code>m</code> .</td>
+</tr>
+<tr>
+<td><code>void swap (identity_matrix &amp;m)</code></td>
+<td>Swaps the contents of the identity matrices.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>identity_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>identity_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>identity_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>identity_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>identity_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>identity_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>identity_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>identity_matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<h2><a name="zero_matrix"></a>Zero Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>zero_matrix&lt;T, ALLOC&gt;</code> represents
+zero matrices. For a <em>(m x n</em>)-dimensional zero matrix and
+<em>0 &lt;= i &lt; m</em>, <em>0 &lt;= j &lt; n</em> holds
+<em>z</em><sub><em>i, j</em></sub> <em>= 0</em>.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    zero_matrix&lt;double&gt; m (3, 3);
+    std::cout &lt;&lt; m &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the matrix.</td>
+<td><code>int</code></td>
+</tr>
+<tr>
+<td><code>ALLOC</code></td>
+<td>An STL Allocator for size_type and difference_type.</td>
+<td>std::allocator</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of
+<a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;zero_matrix&lt;T&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>zero_matrix ()</code></td>
+<td>Constructs a <code>zero_matrix</code> that holds zero rows of
+zero elements.</td>
+</tr>
+<tr>
+<td><code>zero_matrix (size_type size1, size_type
+size2)</code></td>
+<td>Constructs a <code>zero_matrix</code> that holds
+<code>size1</code> rows of <code>size2</code> elements.</td>
+</tr>
+<tr>
+<td><code>zero_matrix (const zero_matrix &amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size1, size_type size2, bool
+preserve = true)</code></td>
+<td>Resizes a <code>zero_matrix</code> to hold <code>size1</code>
+rows of <code>size2</code> elements. Therefore the existing
+elements of the <code>zero_matrix</code> are always preseved.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>zero_matrix &amp;operator = (const zero_matrix
+&amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>zero_matrix &amp;assign_temporary (zero_matrix
+&amp;m)</code></td>
+<td>Assigns a temporary. May change the zero matrix <code>m</code>
+.</td>
+</tr>
+<tr>
+<td><code>void swap (zero_matrix &amp;m)</code></td>
+<td>Swaps the contents of the zero matrices.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>zero_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>zero_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>zero_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>zero_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>zero_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>zero_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>zero_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>zero_matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<h2><a name="scalar_matrix"></a>Scalar Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>scalar_matrix&lt;T, ALLOC&gt;</code>
+represents scalar matrices. For a <em>(m x n</em>)-dimensional
+scalar matrix and <em>0 &lt;= i &lt; m</em>, <em>0 &lt;= j &lt;
+n</em> holds <em>z</em><sub><em>i, j</em></sub> <em>= s</em>.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    scalar_matrix&lt;double&gt; m (3, 3);
+    std::cout &lt;&lt; m &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the matrix.</td>
+<td><code>int</code></td>
+</tr>
+<tr>
+<td><code>ALLOC</code></td>
+<td>An STL Allocator for size_type and difference_type.</td>
+<td>std::allocator</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of
+<a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;scalar_matrix&lt;T&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>scalar_matrix ()</code></td>
+<td>Constructs a <code>scalar_matrix</code> that holds scalar rows
+of zero elements.</td>
+</tr>
+<tr>
+<td><code>scalar_matrix (size_type size1, size_type size2, const
+value_type &amp;value)</code></td>
+<td>Constructs a <code>scalar_matrix</code> that holds
+<code>size1</code> rows of <code>size2</code> elements each of the
+specified value.</td>
+</tr>
+<tr>
+<td><code>scalar_matrix (const scalar_matrix &amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size1, size_type size2, bool
+preserve = true)</code></td>
+<td>Resizes a <code>scalar_matrix</code> to hold <code>size1</code>
+rows of <code>size2</code> elements. Therefore the existing
+elements of the <code>scalar_matrix</code> are always
+preseved.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>scalar_matrix &amp;operator = (const scalar_matrix
+&amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>scalar_matrix &amp;assign_temporary (scalar_matrix
+&amp;m)</code></td>
+<td>Assigns a temporary. May change the scalar matrix
+<code>m</code> .</td>
+</tr>
+<tr>
+<td><code>void swap (scalar_matrix &amp;m)</code></td>
+<td>Swaps the contents of the scalar matrices.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>scalar_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>scalar_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>scalar_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>scalar_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>scalar_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>scalar_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>scalar_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>scalar_matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/matrix_expression.html b/doc/matrix_expression.html
new file mode 100644
index 0000000..a979814
--- /dev/null
+++ b/doc/matrix_expression.html
@@ -0,0 +1,1428 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Matrix Expressions</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Matrix Expressions</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="matrix_expression"></a>Matrix Expression</h2>
+<h4>Description</h4>
+<p>The templated class <code>matrix_expression&lt;E&gt;</code>
+is required to be a public base of all classes which model the Matrix Expression concept.</p>
+<h4>Definition</h4>
+<p>Defined in the header expression_types.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E</code></td>
+<td>The type of the matrix expression.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p>None. <u>Not a Matrix Expression</u>!
+</p>
+<h4>Type requirements</h4>
+<p>None.</p>
+<h4>Public base classes</h4>
+<p>None.</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>const expression_type &amp;operator () ()
+const</code></td>
+<td>Returns a <code>const</code> reference of the expression.</td>
+</tr>
+<tr>
+<td><code>expression_type &amp;operator () ()</code></td>
+<td>Returns a reference of the expression.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p>The <code>operator[]</code>, <code>row</code>, <code>column</code>, <code>range</code>, <code>slice</code> and <code>project</code> functions have been removed. Use the free functions defined in <a href="matrix_proxy.html">matrix proxy</a> instead.</p>
+<h2><a name="matrix_container"></a>Matrix Container</h2>
+<h4>Description</h4>
+<p>The templated class <code>matrix_container&lt;C&gt;</code>
+is required to be a public base of all classes which model the Matrix concept.
+This includes the class <code>matrix</code> itself.</p>
+<h4>Definition</h4>
+<p>Defined in the header expression_types.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E</code></td>
+<td>The type of the matrix expression.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p>None. <u>Not a Matrix Expression OR Matrix</u>!
+</p>
+<h4>Type requirements</h4>
+<p>None.</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;C&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>const container_type &amp;operator () ()
+const</code></td>
+<td>Returns a <code>const</code> reference of the container.</td>
+</tr>
+<tr>
+<td><code>container_type &amp;operator () ()</code></td>
+<td>Returns a reference of the container.</td>
+</tr>
+</tbody>
+</table>
+<h2><a name="matrix_references"></a>Matrix References</h2>
+<h3>Reference</h3>
+<h4>Description</h4>
+<p>The templated class <code>matrix_reference&lt;E&gt;</code>
+contains a reference to a matrix expression.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E</code></td>
+<td>The type of the matrix expression.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;matrix_reference&lt;E&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_reference (expression_type &amp;e)</code></td>
+<td>Constructs a constant reference of the expression.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size1, size2)</code></td>
+<td>Resizes the expression to hold at most <code>size1</code> rows
+of <code>size2</code> elements.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the expression.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the expression.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h2><a name="matrix_operations"></a>Matrix Operations</h2>
+<h3>Unary Operation Description</h3>
+<h4>Description</h4>
+<p>The templated classes <code>matrix_unary1&lt;E, F&gt;</code> and
+<code>matrix_unary2&lt;E, F&gt;</code> describe unary matrix
+operations.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E</code></td>
+<td>The type of the matrix expression.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>The type of the operation.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;matrix_unary1&lt;E, F&gt; &gt;</code>
+and <code>matrix_expression&lt;matrix_unary2&lt;E, F&gt;
+&gt;</code> resp.</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_unary1 (const expression_type &amp;e)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>matrix_unary2 (const expression_type &amp;e)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h3>Unary Operations</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class E, class F&gt;
+    struct matrix_unary1_traits {
+        typedef matrix_unary1&lt;typename E::const_closure_type, F&gt; expression_type;
+        typedef expression_type result_type;
+     };
+
+    // (- m) [i] [j] = - m [i] [j]
+    template&lt;class E&gt;
+     typename matrix_unary1_traits&lt;E, scalar_negate&lt;typename E::value_type&gt; &gt;::result_type
+    operator - (const matrix_expression&lt;E&gt; &amp;e);
+
+    // (conj m) [i] [j] = conj (m [i] [j])
+    template&lt;class E&gt;
+     typename matrix_unary1_traits&lt;E, scalar_conj&lt;typename E::value_type&gt; &gt;::result_type
+    conj (const matrix_expression&lt;E&gt; &amp;e);
+
+    // (real m) [i] [j] = real (m [i] [j])
+    template&lt;class E&gt;
+     typename matrix_unary1_traits&lt;E, scalar_real&lt;typename E::value_type&gt; &gt;::result_type
+    real (const matrix_expression&lt;E&gt; &amp;e);
+
+    // (imag m) [i] [j] = imag (m [i] [j])
+    template&lt;class E&gt;
+     typename matrix_unary1_traits&lt;E, scalar_imag&lt;typename E::value_type&gt; &gt;::result_type
+    imag (const matrix_expression&lt;E&gt; &amp;e);
+
+    template&lt;class E, class F&gt;
+    struct matrix_unary2_traits {
+        typedef matrix_unary2&lt;typename E::const_closure_type, F&gt; expression_type;
+        typedef expression_type result_type;
+     };
+
+    // (trans m) [i] [j] = m [j] [i]
+    template&lt;class E&gt;
+     typename matrix_unary2_traits&lt;E, scalar_identity&lt;typename E::value_type&gt; &gt;::result_type
+    trans (const matrix_expression&lt;E&gt; &amp;e);
+
+    // (herm m) [i] [j] = conj (m [j] [i])
+    template&lt;class E&gt;
+     typename matrix_unary2_traits&lt;E, scalar_conj&lt;typename E::value_type&gt; &gt;::result_type
+    herm (const matrix_expression&lt;E&gt; &amp;e);</code>
+</pre>
+<h4>Description</h4>
+<p><code>operator -</code> computes the additive inverse of a
+matrix expression. <code>conj</code> computes the complex conjugate
+of a matrix expression. <code>real</code> and <code>imag</code>
+compute the real and imaginary parts of a matrix expression.
+<code>trans</code> computes the transpose of a matrix expression.
+<code>herm</code> computes the hermitian, i.e. the complex
+conjugate of the transpose of a matrix expression.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<p>None.</p>
+<h4>Complexity</h4>
+<p>Quadratic depending from the size of the matrix expression.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;std::complex&lt;double&gt; &gt; m (3, 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            m (i, j) = std::complex&lt;double&gt; (3 * i + j, 3 * i + j);
+
+    std::cout &lt;&lt; - m &lt;&lt; std::endl;
+    std::cout &lt;&lt; conj (m) &lt;&lt; std::endl;
+    std::cout &lt;&lt; real (m) &lt;&lt; std::endl;
+    std::cout &lt;&lt; imag (m) &lt;&lt; std::endl;
+    std::cout &lt;&lt; trans (m) &lt;&lt; std::endl;
+    std::cout &lt;&lt; herm (m) &lt;&lt; std::endl;
+}
+</pre>
+<h3>Binary Operation Description</h3>
+<h4>Description</h4>
+<p>The templated class <code>matrix_binary&lt;E1, E2, F&gt;</code>
+describes a binary matrix operation.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E1</code></td>
+<td>The type of the first matrix expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>E2</code></td>
+<td>The type of the second matrix expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>The type of the operation.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;matrix_binary&lt;E1, E2, F&gt;
+&gt;</code>.</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_binary (const expression1_type &amp;e1, const
+expression2_type &amp;e2)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h3>Binary Operations</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class E1, class E2, class F&gt;
+    struct matrix_binary_traits {
+        typedef matrix_binary&lt;typename E1::const_closure_type,
+                               typename E2::const_closure_type, F&gt; expression_type;
+        typedef expression_type result_type;
+     };
+
+    // (m1 + m2) [i] [j] = m1 [i] [j] + m2 [i] [j]
+    template&lt;class E1, class E2&gt;
+    typename matrix_binary_traits&lt;E1, E2, scalar_plus&lt;typename E1::value_type,
+                                                       typename E2::value_type&gt; &gt;::result_type
+    operator + (const matrix_expression&lt;E1&gt; &amp;e1,
+                 const matrix_expression&lt;E2&gt; &amp;e2);
+
+    // (m1 - m2) [i] [j] = m1 [i] [j] - m2 [i] [j]
+    template&lt;class E1, class E2&gt;
+    typename matrix_binary_traits&lt;E1, E2, scalar_minus&lt;typename E1::value_type,
+                                                        typename E2::value_type&gt; &gt;::result_type
+    operator - (const matrix_expression&lt;E1&gt; &amp;e1,
+                 const matrix_expression&lt;E2&gt; &amp;e2);</code>
+</pre>
+<h4>Description</h4>
+<p><code>operator +</code> computes the sum of two matrix
+expressions. <code>operator -</code> computes the difference of two
+matrix expressions.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E1</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+<li><code>E2</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<ul>
+<li><code>e1 ().size1 () == e2 ().size1 ()</code></li>
+<li><code>e1 ().size2 () == e2 ().size2 ()</code></li>
+</ul>
+<h4>Complexity</h4>
+<p>Quadratic depending from the size of the matrix expressions.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m1 (3, 3), m2 (3, 3);
+    for (unsigned i = 0; i &lt; std::min (m1.size1 (), m2.size1 ()); ++ i)
+        for (unsigned j = 0; j &lt; std::min (m1.size2 (), m2.size2 ()); ++ j)
+            m1 (i, j) = m2 (i, j) = 3 * i + j;
+
+    std::cout &lt;&lt; m1 + m2 &lt;&lt; std::endl;
+    std::cout &lt;&lt; m1 - m2 &lt;&lt; std::endl;
+}
+</pre>
+<h3>Scalar Matrix Operation Description</h3>
+<h4>Description</h4>
+<p>The templated classes <code>matrix_binary_scalar1&lt;E1, E2,
+F&gt;</code> and <code>matrix_binary_scalar2&lt;E1, E2,
+F&gt;</code> describe binary operations between a scalar and a
+matrix.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E1/E2</code></td>
+<td>The type of the scalar expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>E2/E1</code></td>
+<td>The type of the matrix expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>The type of the operation.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;matrix_binary_scalar1&lt;E1, E2,
+F&gt; &gt;</code> and
+<code>matrix_expression&lt;matrix_binary_scalar2&lt;E1, E2, F&gt;
+&gt;</code> resp.</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_binary_scalar1 (const expression1_type &amp;e1,
+const expression2_type &amp;e2)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>matrix_binary_scalar1 (const expression1_type &amp;e1,
+const expression2_type &amp;e2)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h3>Scalar Matrix Operations</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class T1, class E2, class F&gt;
+    struct matrix_binary_scalar1_traits {
+        typedef matrix_binary_scalar1&lt;scalar_const_reference&lt;T1&gt;,
+                                      typename E2::const_closure_type, F&gt; expression_type;
+        typedef expression_type result_type;
+     };
+
+    // (t * m) [i] [j] = t * m [i] [j]
+    template&lt;class T1, class E2&gt;
+    typename matrix_binary_scalar1_traits&lt;T1, E2, scalar_multiplies&lt;T1, typename E2::value_type&gt; &gt;::result_type
+    operator * (const T1 &amp;e1,
+                 const matrix_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class E1, class T2, class F&gt;
+    struct matrix_binary_scalar2_traits {
+        typedef matrix_binary_scalar2&lt;typename E1::const_closure_type,
+                                      scalar_const_reference&lt;T2&gt;, F&gt; expression_type;
+        typedef expression_type result_type;
+     };
+
+    // (m * t) [i] [j] = m [i] [j] * t
+    template&lt;class E1, class T2&gt;
+    typename matrix_binary_scalar2_traits&lt;E1, T2, scalar_multiplies&lt;typename E1::value_type, T2&gt; &gt;::result_type
+    operator * (const matrix_expression&lt;E1&gt; &amp;e1,
+                 const T2 &amp;e2);
+
+    // (m / t) [i] [j] = m [i] [j] / t
+    template&lt;class E1, class T2&gt;
+    typename matrix_binary_scalar2_traits&lt;E1, T2, scalar_divides&lt;typename E1::value_type, T2&gt; &gt;::result_type
+    operator / (const matrix_expression&lt;E1&gt; &amp;e1,
+                 const T2 &amp;e2);</code>
+</pre>
+<h4>Description</h4>
+<p><code>operator *</code> computes the product of a scalar and a
+matrix expression. <code>operator /</code> multiplies the matrix
+with the reciprocal of the scalar.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>T1/T2</code> is a model of <a href=
+"expression_concept.html#scalar_expression">Scalar Expression</a> .</li>
+<li><code>E2/E1</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<p>None.</p>
+<h4>Complexity</h4>
+<p>Quadratic depending from the size of the matrix expression.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+
+    std::cout &lt;&lt; 2.0 * m &lt;&lt; std::endl;
+    std::cout &lt;&lt; m * 2.0 &lt;&lt; std::endl;
+}
+</pre>
+<h2><a name="matrix_vector_operations"></a>Matrix Vector Operations</h2>
+<h3>Binary Operation Description</h3>
+<h4>Description</h4>
+<p>The templated classes <code>matrix_vector_binary1&lt;E1, E2,
+F&gt;</code> and <code>matrix_vector_binary2&lt;E1, E2,
+F&gt;</code> describe binary matrix vector operations.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E1</code></td>
+<td>The type of the matrix or vector expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>E2</code></td>
+<td>The type of the vector or matrix expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>The type of the operation.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;matrix_vector_binary1&lt;E1, E2,
+F&gt; &gt;</code> and
+<code>vector_expression&lt;matrix_vector_binary2&lt;E1, E2, F&gt;
+&gt;</code> resp.</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_vector_binary1 (const expression1_type &amp;e1,
+const expression2_type &amp;e2)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>matrix_vector_binary2 (const expression1_type &amp;e1,
+const expression2_type &amp;e2)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the expression.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h3>Binary Operations</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class T1, class E1, class T2, class E2&gt;
+    struct matrix_vector_binary1_traits {
+        typedef row_major_tag dispatch_category;
+        typedef typename promote_traits&lt;T1, T2&gt;::promote_type promote_type;
+        typedef matrix_vector_binary1&lt;typename E1::const_closure_type,
+                                       typename E2::const_closure_type,
+                                       matrix_vector_prod1&lt;T1, T2, promote_type&gt; &gt; expression_type;
+        typedef expression_type result_type;
+     };
+
+    template&lt;class E1, class E2&gt;
+    typename matrix_vector_binary1_traits&lt;typename E1::value_type, E1,
+                                           typename E2::value_type, E2&gt;::result_type
+    prod (const matrix_expression&lt;E1&gt; &amp;e1,
+           const vector_expression&lt;E2&gt; &amp;e2,
+          row_major_tag);
+
+    // Dispatcher
+    template&lt;class E1, class E2&gt;
+    typename matrix_vector_binary1_traits&lt;typename E1::value_type, E1,
+                                           typename E2::value_type, E2&gt;::result_type
+    prod (const matrix_expression&lt;E1&gt; &amp;e1,
+           const vector_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class E1, class E2&gt;
+    typename matrix_vector_binary1_traits&lt;typename type_traits&lt;typename E1::value_type&gt;::precision_type, E1,
+                                           typename type_traits&lt;typename E2::value_type&gt;::precision_type, E2&gt;::result_type
+    prec_prod (const matrix_expression&lt;E1&gt; &amp;e1,
+                const vector_expression&lt;E2&gt; &amp;e2,
+               row_major_tag);
+
+    // Dispatcher
+    template&lt;class E1, class E2&gt;
+    typename matrix_vector_binary1_traits&lt;typename type_traits&lt;typename E1::value_type&gt;::precision_type, E1,
+                                           typename type_traits&lt;typename E2::value_type&gt;::precision_type, E2&gt;::result_type
+    prec_prod (const matrix_expression&lt;E1&gt; &amp;e1,
+                const vector_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class V, class E1, class E2&gt;
+    V
+    prod (const matrix_expression&lt;E1&gt; &amp;e1,
+          const vector_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class V, class E1, class E2&gt;
+    V
+    prec_prod (const matrix_expression&lt;E1&gt; &amp;e1,
+               const vector_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class T1, class E1, class T2, class E2&gt;
+    struct matrix_vector_binary2_traits {
+        typedef column_major_tag dispatch_category;
+        typedef typename promote_traits&lt;T1, T2&gt;::promote_type promote_type;
+        typedef matrix_vector_binary2&lt;typename E1::const_closure_type,
+                                       typename E2::const_closure_type,
+                                       matrix_vector_prod2&lt;T1, T2, promote_type&gt; &gt; expression_type;
+        typedef expression_type result_type;
+     };
+
+    template&lt;class E1, class E2&gt;
+    typename matrix_vector_binary2_traits&lt;typename E1::value_type, E1,
+                                           typename E2::value_type, E2&gt;::result_type
+    prod (const vector_expression&lt;E1&gt; &amp;e1,
+           const matrix_expression&lt;E2&gt; &amp;e2,
+          column_major_tag);
+
+    // Dispatcher
+    template&lt;class E1, class E2&gt;
+    typename matrix_vector_binary2_traits&lt;typename E1::value_type, E1,
+                                           typename E2::value_type, E2&gt;::result_type
+    prod (const vector_expression&lt;E1&gt; &amp;e1,
+           const matrix_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class E1, class E2&gt;
+    typename matrix_vector_binary2_traits&lt;typename type_traits&lt;typename E1::value_type&gt;::precision_type, E1,
+                                           typename type_traits&lt;typename E2::value_type&gt;::precision_type, E2&gt;::result_type
+    prec_prod (const vector_expression&lt;E1&gt; &amp;e1,
+                const matrix_expression&lt;E2&gt; &amp;e2,
+               column_major_tag);
+
+    // Dispatcher
+    template&lt;class E1, class E2&gt;
+    typename matrix_vector_binary2_traits&lt;typename type_traits&lt;typename E1::value_type&gt;::precision_type, E1,
+                                           typename type_traits&lt;typename E2::value_type&gt;::precision_type, E2&gt;::result_type
+    prec_prod (const vector_expression&lt;E1&gt; &amp;e1,
+                const matrix_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class V, class E1, class E2&gt;
+    V
+    prod (const vector_expression&lt;E1&gt; &amp;e1,
+          const matrix_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class V, class E1, class E2&gt;
+    V
+    prec_prod (const vector_expression&lt;E1&gt; &amp;e1,
+               const matrix_expression&lt;E2&gt; &amp;e2);</code>
+</pre>
+<h4>Description</h4>
+<p><code>prod</code> computes the product of the matrix and the
+vector expression. <code>prec_prod</code> computes the double
+precision product of the matrix and the vector expression.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E1</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> or
+<a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</li>
+<li><code>E2</code> is a model of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> or
+<a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</li>
+</ul>
+<h4>Preconditions</h4>
+<ul>
+<li><code>e1 ().size2 () == e2 ().size ()</code></li>
+<li><code>e1 ().size () == e2 ().size1 ()</code></li>
+</ul>
+<h4>Complexity</h4>
+<p>Quadratic depending from the size of the matrix expression.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    vector&lt;double&gt; v (3);
+    for (unsigned i = 0; i &lt; std::min (m.size1 (), v.size ()); ++ i) {
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+        v (i) = i;
+    }
+
+    std::cout &lt;&lt; prod (m, v) &lt;&lt; std::endl;
+    std::cout &lt;&lt; prod (v, m) &lt;&lt; std::endl;
+}
+</pre>
+<h3>Triangular Solver</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class E1, class E2&gt;
+    struct matrix_vector_solve_traits {
+        typedef typename promote_traits&lt;typename E1::value_type, typename E2::value_type&gt;::promote_type promote_type;
+        typedef vector&lt;promote_type&gt; result_type;
+    };
+
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (const matrix_expression&lt;E1&gt; &amp;e1,
+                         E2 &amp;e2,
+                        lower_tag,
+                        vector_tag);
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (const matrix_expression&lt;E1&gt; &amp;e1,
+                         E2 &amp;e2,
+                        upper_tag,
+                        vector_tag);
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (const matrix_expression&lt;E1&gt; &amp;e1,
+                         E2 &amp;e2,
+                        unit_lower_tag,
+                        vector_tag);
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (const matrix_expression&lt;E1&gt; &amp;e1,
+                         E2 &amp;e2,
+                        unit_upper_tag,
+                        vector_tag);
+
+    template&lt;class E1, class E2, class C&gt;
+    typename matrix_vector_solve_traits&lt;E1, E2&gt;::result_type
+    solve (const matrix_expression&lt;E1&gt; &amp;e1,
+            const vector_expression&lt;E2&gt; &amp;e2,
+           C);
+
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (E1 &amp;e1,
+                        const matrix_expression&lt;E2&gt; &amp;e2,
+                         vector_tag,
+                         lower_tag);
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (E1 &amp;e1,
+                        const matrix_expression&lt;E2&gt; &amp;e2,
+                         vector_tag,
+                         upper_tag);
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (E1 &amp;e1,
+                        const matrix_expression&lt;E2&gt; &amp;e2,
+                         vector_tag,
+                         unit_lower_tag);
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (E1 &amp;e1,
+                        const matrix_expression&lt;E2&gt; &amp;e2,
+                         vector_tag,
+                         unit_upper_tag);
+
+    template&lt;class E1, class E2, class C&gt;
+    typename matrix_vector_solve_traits&lt;E1, E2&gt;::result_type
+    solve (const vector_expression&lt;E1&gt; &amp;e1,
+            const matrix_expression&lt;E2&gt; &amp;e2,
+           C);</code>
+</pre>
+<h4>Description</h4>
+<p><code>solve</code> solves a linear equation for lower or upper
+(unit) triangular matrices.</p>
+<h4>Definition</h4>
+<p>Defined in the header triangular.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E1</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> or
+<a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</li>
+<li><code>E2</code> is a model of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> or
+<a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</li>
+</ul>
+<h4>Preconditions</h4>
+<ul>
+<li><code>e1 ().size1 () == e1 ().size2 ()</code></li>
+<li><code>e1 ().size2 () == e2 ().size ()</code></li>
+<li><code>e1 ().size () == e2 ().size1 ()</code></li>
+<li><code>e2 ().size1 () == e2 ().size2 ()</code></li>
+</ul>
+<h4>Complexity</h4>
+<p>Quadratic depending from the size of the matrix expression.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/triangular.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    vector&lt;double&gt; v (3);
+    for (unsigned i = 0; i &lt; std::min (m.size1 (), v.size ()); ++ i) {
+        for (unsigned j = 0; j &lt;= i; ++ j)
+            m (i, j) = 3 * i + j + 1;
+        v (i) = i;
+    }
+
+    std::cout &lt;&lt; solve (m, v, lower_tag ()) &lt;&lt; std::endl;
+    std::cout &lt;&lt; solve (v, m, lower_tag ()) &lt;&lt; std::endl;
+}
+</pre>
+<h2><a name="matrix_matrix_operations"></a>Matrix Matrix Operations</h2>
+<h3>Binary Operation Description</h3>
+<h4>Description</h4>
+<p>The templated class <code>matrix_matrix_binary&lt;E1, E2,
+F&gt;</code> describes a binary matrix operation.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E1</code></td>
+<td>The type of the first matrix expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>E2</code></td>
+<td>The type of the second matrix expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>The type of the operation.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;matrix_matrix_binary&lt;E1, E2, F&gt;
+&gt;</code> .</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_matrix_binary (const expression1_type &amp;e1,
+const expression2_type &amp;e2)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h3>Binary Operations</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class T1, class E1, class T2, class E2&gt;
+    struct matrix_matrix_binary_traits {
+        typedef unknown_orientation_tag dispatch_category;
+        typedef typename promote_traits&lt;T1, T2&gt;::promote_type promote_type;
+        typedef matrix_matrix_binary&lt;typename E1::const_closure_type,
+                                     typename E2::const_closure_type,
+                                     matrix_matrix_prod&lt;T1, T2, promote_type&gt; &gt; expression_type;
+        typedef expression_type result_type;
+    };
+
+    template&lt;class E1, class E2&gt;
+    typename matrix_matrix_binary_traits&lt;typename E1::value_type, E1,
+                                         typename E2::value_type, E2&gt;::result_type
+    prod (const matrix_expression&lt;E1&gt; &amp;e1,
+          const matrix_expression&lt;E2&gt; &amp;e2,
+          unknown_orientation_tag);
+
+    // Dispatcher
+    template&lt;class E1, class E2&gt;
+    typename matrix_matrix_binary_traits&lt;typename E1::value_type, E1,
+                                         typename E2::value_type, E2&gt;::result_type
+    prod (const matrix_expression&lt;E1&gt; &amp;e1,
+          const matrix_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class E1, class E2&gt;
+    typename matrix_matrix_binary_traits&lt;typename type_traits&lt;typename E1::value_type&gt;::precision_type, E1,
+                                         typename type_traits&lt;typename E2::value_type&gt;::precision_type, E2&gt;::result_type
+    prec_prod (const matrix_expression&lt;E1&gt; &amp;e1,
+               const matrix_expression&lt;E2&gt; &amp;e2,
+               unknown_orientation_tag);
+
+    // Dispatcher
+    template&lt;class E1, class E2&gt;
+    typename matrix_matrix_binary_traits&lt;typename type_traits&lt;typename E1::value_type&gt;::precision_type, E1,
+                                         typename type_traits&lt;typename E2::value_type&gt;::precision_type, E2&gt;::result_type
+    prec_prod (const matrix_expression&lt;E1&gt; &amp;e1,
+               const matrix_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class M, class E1, class E2&gt;
+    M
+    prod (const matrix_expression&lt;E1&gt; &amp;e1,
+          const matrix_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class M, class E1, class E2&gt;
+    M
+    prec_prod (const matrix_expression&lt;E1&gt; &amp;e1,
+               const matrix_expression&lt;E2&gt; &amp;e2);</code>
+</pre>
+<h4>Description</h4>
+<p><code>prod</code> computes the product of the matrix
+expressions. <code>prec_prod</code> computes the double precision
+product of the matrix expressions.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E1</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+<li><code>E2</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<ul>
+<li><code>e1 ().size2 () == e2 ().size1 ()</code></li>
+</ul>
+<h4>Complexity</h4>
+<p>Cubic depending from the size of the matrix expression.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m1 (3, 3), m2 (3, 3);
+    for (unsigned i = 0; i &lt; std::min (m1.size1 (), m2.size1 ()); ++ i)
+        for (unsigned j = 0; j &lt; std::min (m1.size2 (), m2.size2 ()); ++ j)
+            m1 (i, j) = m2 (i, j) = 3 * i + j;
+
+    std::cout &lt;&lt; prod (m1, m2) &lt;&lt; std::endl;
+}
+</pre>
+<h3>Triangular Solvers</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class E1, class E2&gt;
+    struct matrix_matrix_solve_traits {
+        typedef typename promote_traits&lt;typename E1::value_type, typename E2::value_type&gt;::promote_type promote_type;
+        typedef matrix&lt;promote_type&gt; result_type;
+    };
+
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (const matrix_expression&lt;E1&gt; &amp;e1,
+                        E2 &amp;e2,
+                        lower_tag,
+                        matrix_tag);
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (const matrix_expression&lt;E1&gt; &amp;e1,
+                        E2 &amp;e2,
+                        upper_tag,
+                        matrix_tag);
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (const matrix_expression&lt;E1&gt; &amp;e1,
+                        E2 &amp;e2,
+                        unit_lower_tag,
+                        matrix_tag);
+    template&lt;class E1, class E2&gt;
+    void inplace_solve (const matrix_expression&lt;E1&gt; &amp;e1,
+                        E2 &amp;e2,
+                        unit_upper_tag,
+                        matrix_tag);
+
+    template&lt;class E1, class E2, class C&gt;
+    typename matrix_matrix_solve_traits&lt;E1, E2&gt;::result_type
+    solve (const matrix_expression&lt;E1&gt; &amp;e1,
+           const matrix_expression&lt;E2&gt; &amp;e2,
+           C);</code>
+</pre>
+<h4>Description</h4>
+<p><code>solve</code> solves a linear equation for lower or upper
+(unit) triangular matrices.</p>
+<h4>Definition</h4>
+<p>Defined in the header triangular.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E1</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+<li><code>E2</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<ul>
+<li><code>e1 ().size1 () == e1 ().size2 ()</code></li>
+<li><code>e1 ().size2 () == e2 ().size1 ()</code></li>
+</ul>
+<h4>Complexity</h4>
+<p>Cubic depending from the size of the matrix expressions.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/triangular.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m1 (3, 3), m2 (3, 3);
+    for (unsigned i = 0; i &lt; std::min (m1.size1 (), m2.size1 ()); ++ i)
+        for (unsigned j = 0; j &lt;= i; ++ j)
+            m1 (i, j) = m2 (i, j) = 3 * i + j + 1;
+
+    std::cout &lt;&lt; solve (m1, m2, lower_tag ()) &lt;&lt; std::endl;
+}
+</pre>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/matrix_proxy.html b/doc/matrix_proxy.html
new file mode 100644
index 0000000..d4b4202
--- /dev/null
+++ b/doc/matrix_proxy.html
@@ -0,0 +1,1428 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Matrix Proxies</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Matrix Proxies</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="matrix_row"></a>Matrix Row</h2>
+<h4>Description</h4>
+<p>The templated class <code>matrix_row&lt;M&gt;</code> allows
+addressing a row of a matrix.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i) {
+        matrix_row&lt;matrix&lt;double&gt; &gt; mr (m, i);
+        for (unsigned j = 0; j &lt; mr.size (); ++ j)
+            mr (j) = 3 * i + j;
+        std::cout &lt;&lt; mr &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_proxy.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>M</code></td>
+<td>The type of matrix referenced.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<p>If the specified row falls outside that of the row index range
+of the matrix, then the <code>matrix_row</code> is not a well
+formed Vector Expression. That is, access to an element which is
+outside of the matrix is <i>undefined</i>.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;matrix_row&lt;M&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_row (matrix_type &amp;data, size_type
+i)</code></td>
+<td>Constructs a sub vector.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the sub vector.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>matrix_row &amp;operator = (const matrix_row
+&amp;mr)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>matrix_row &amp;assign_temporary (matrix_row
+&amp;mr)</code></td>
+<td>Assigns a temporary. May change the matrix row <code>mr</code>
+.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_row &amp;operator = (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_row &amp;assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a vector expression to the sub vector. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_row &amp;operator += (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the vector expression to
+the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_row &amp;plus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a vector expression to the sub vector. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_row &amp;operator -= (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the vector expression
+from the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_row &amp;minus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a vector expression from the sub vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_row &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the sub vector with
+a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_row &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the sub vector through
+a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (matrix_row &amp;mr)</code></td>
+<td>Swaps the contents of the sub vectors.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>matrix_row</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>matrix_row</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>matrix_row</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>matrix_row</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>matrix_row</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>matrix_row</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>matrix_row</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>matrix_row</code>.</td>
+</tr>
+</tbody>
+</table>
+<h3>Projections</h3>
+<h4>Description</h4>
+<p>The free <code>row</code> functions support the construction of
+matrix rows.</p>
+<h4>Prototypes</h4>
+<pre><code>
+    template&lt;class M&gt;
+    matrix_row&lt;M&gt; row (M &amp;data, std::size_t i);
+    template&lt;class M&gt;
+    const matrix_row&lt;const M&gt; row (const M &amp;data, std::size_t i);
+</code></pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_proxy.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>M</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+</ul>
+<h4>Complexity</h4>
+<p>Linear depending from the size of the row.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i) {
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            row (m, i) (j) = 3 * i + j;
+        std::cout &lt;&lt; row (m, i) &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h2><a name="matrix_column"></a>Matrix Column</h2>
+<h4>Description</h4>
+<p>The templated class <code>matrix_column&lt;M&gt;</code> allows
+addressing a column of a matrix.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    for (unsigned j = 0; j &lt; m.size2 (); ++ j) {
+        matrix_column&lt;matrix&lt;double&gt; &gt; mc (m, j);
+        for (unsigned i = 0; i &lt; mc.size (); ++ i)
+            mc (i) = 3 * i + j;
+        std::cout &lt;&lt; mc &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_proxy.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>M</code></td>
+<td>The type of matrix referenced.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<p>If the specified column falls outside that of the column index
+range of the matrix, then the <code>matrix_column</code> is not a
+well formed Vector Expression. That is, access to an element which
+is outside of the matrix is <i>undefined</i>.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;matrix_column&lt;M&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_column (matrix_type &amp;data, size_type
+j)</code></td>
+<td>Constructs a sub vector.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the sub vector.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>matrix_column &amp;operator = (const matrix_column
+&amp;mc)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>matrix_column &amp;assign_temporary (matrix_column
+&amp;mc)</code></td>
+<td>Assigns a temporary. May change the matrix column
+<code>mc</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_column &amp;operator = (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_column &amp;assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a vector expression to the sub vector. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_column &amp;operator += (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the vector expression to
+the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_column &amp;plus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a vector expression to the sub vector. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_column &amp;operator -= (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the vector expression
+from the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_column &amp;minus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a vector expression from the sub vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_column &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the sub vector with
+a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_column &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the sub vector through
+a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (matrix_column &amp;mc)</code></td>
+<td>Swaps the contents of the sub vectors.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>matrix_column</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>matrix_column</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>matrix_column</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>matrix_column</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>matrix_column</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>matrix_column</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>matrix_column</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>matrix_column</code>.</td>
+</tr>
+</tbody>
+</table>
+<h3>Projections</h3>
+<h4>Description</h4>
+<p>The free <code>column</code> functions support the construction
+of matrix columns.</p>
+<h4>Prototypes</h4>
+<pre><code>
+    template&lt;class M&gt;
+    matrix_column&lt;M&gt; column (M &amp;data, std::size_t j);
+    template&lt;class M&gt;
+    const matrix_column&lt;const M&gt; column (const M &amp;data, std::size_t j);
+</code></pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_proxy.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>M</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+</ul>
+<h4>Complexity</h4>
+<p>Linear depending from the size of the column.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    for (unsigned j = 0; j &lt; m.size2 (); ++ j) {
+        for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+            column (m, j) (i) = 3 * i + j;
+        std::cout &lt;&lt; column (m, j) &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h2><a name="vector_range"></a>Vector Range</h2>
+<h4>Description</h4>
+<p>The templated class <code>matrix_vector_range&lt;M&gt;</code>
+allows addressing a sub vector of a matrix.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+
+    matrix_vector_range&lt;matrix&lt;double&gt; &gt; mvr (m, range (0, 3), range (0, 3));
+    std::cout &lt;&lt; mvr &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_proxy.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>M</code></td>
+<td>The type of matrix referenced.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<p>If the specified ranges fall outside that of the index range of
+the matrix, then the <code>matrix_vector_range</code> is not a well
+formed Vector Expression. That is, access to an element which is
+outside of the matrix is <i>undefined</i>.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;matrix_vector_range&lt;M&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_vector_range (matrix_type &amp;data,<br />
+const range &amp;r1, const range &amp;r2)</code></td>
+<td>Constructs a sub vector.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the sub vector.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>matrix_vector_range &amp;operator = (const
+matrix_vector_range &amp;mvr)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>matrix_vector_range &amp;assign_temporary
+(matrix_vector_range &amp;mvr)</code></td>
+<td>Assigns a temporary. May change the matrix vector range
+<code>mvr</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_range &amp;operator = (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_range &amp;assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a vector expression to the sub vector. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_range &amp;operator += (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the vector expression to
+the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_range &amp;plus_assign (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a vector expression to the sub vector. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_range &amp;operator -= (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the vector expression
+from the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_range &amp;minus_assign (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a vector expression from the sub vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_vector_range &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the sub vector with
+a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_vector_range &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the sub vector through
+a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (matrix_vector_range &amp;mvr)</code></td>
+<td>Swaps the contents of the sub vectors.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>matrix_vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>matrix_vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>matrix_vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>matrix_vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the <code>matrix_vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>matrix_vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>matrix_vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>matrix_vector_range</code>.</td>
+</tr>
+</tbody>
+</table>
+<h2><a name="vector_slice"></a>Vector Slice</h2>
+<h4>Description</h4>
+<p>The templated class <code>matrix_vector_slice&lt;M&gt;</code>
+allows addressing a sliced sub vector of a matrix.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+
+    matrix_vector_slice&lt;matrix&lt;double&gt; &gt; mvs (m, slice (0, 1, 3), slice (0, 1, 3));
+    std::cout &lt;&lt; mvs &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_proxy.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>M</code></td>
+<td>The type of matrix referenced.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<p>If the specified slices fall outside that of the index range of
+the matrix, then the <code>matrix_vector_slice</code> is not a well
+formed Vector Expression. That is, access to an element which is
+outside of the matrix is <i>undefined</i>.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;matrix_vector_slice&lt;M&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_vector_slice (matrix_type &amp;data,<br />
+const slice &amp;s1, const slice &amp;s2)</code></td>
+<td>Constructs a sub vector.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the sub vector.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>matrix_vector_slice &amp;operator = (const
+matrix_vector_slice &amp;mvs)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>matrix_vector_slice &amp;assign_temporary
+(matrix_vector_slice &amp;mvs)</code></td>
+<td>Assigns a temporary. May change the matrix vector slice
+<code>vs</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_slice &amp;operator = (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_slice &amp;assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a vector expression to the sub vector. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_slice &amp;operator += (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the vector expression to
+the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_slice &amp;plus_assign (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a vector expression to the sub vector. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_slice &amp;operator -= (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the vector expression
+from the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_vector_slice &amp;minus_assign (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a vector expression from the sub vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_vector_slice &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the sub vector with
+a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_vector_slice &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the sub vector through
+a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (matrix_vector_slice &amp;mvs)</code></td>
+<td>Swaps the contents of the sub vectors.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>matrix_vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>matrix_vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>matrix_vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>matrix_vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>matrix_vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>matrix_vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>matrix_vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>matrix_vector_slice</code>.</td>
+</tr>
+</tbody>
+</table>
+<h2><a name="matrix_range"></a>Matrix Range</h2>
+<h4>Description</h4>
+<p>The templated class <code>matrix_range&lt;M&gt;</code> allows
+addressing a sub matrix of a matrix.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    matrix_range&lt;matrix&lt;double&gt; &gt; mr (m, range (0, 3), range (0, 3));
+    for (unsigned i = 0; i &lt; mr.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; mr.size2 (); ++ j)
+            mr (i, j) = 3 * i + j;
+    std::cout &lt;&lt; mr &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_proxy.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>M</code></td>
+<td>The type of matrix referenced.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<p>If the specified ranges fall outside that of the index range of
+the matrix, then the <code>matrix_range</code> is not a well formed
+Matrix Expression. That is, access to an element which is outside
+of the matrix is <i>undefined</i>.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;matrix_range&lt;M&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_range (matrix_type &amp;data,<br />
+const range &amp;r1, const range &amp;r2)</code></td>
+<td>Constructs a sub matrix.</td>
+</tr>
+<tr>
+<td><code>size_type start1 () const</code></td>
+<td>Returns the index of the first row.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type start2 () const</code></td>
+<td>Returns the index of the first column.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>matrix_range &amp;operator = (const matrix_range
+&amp;mr)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>matrix_range &amp;assign_temporary (matrix_range
+&amp;mr)</code></td>
+<td>Assigns a temporary. May change the matrix range
+<code>mr</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_range &amp;operator = (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_range &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the sub matrix. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_range &amp;operator += (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the sub matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_range &amp;plus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a matrix expression to the sub matrix. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_range &amp;operator -= (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the sub matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_range &amp;minus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a matrix expression from the sub matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_range &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the sub matrix with
+a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_range &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the sub matrix through
+a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (matrix_range &amp;mr)</code></td>
+<td>Swaps the contents of the sub matrices.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>matrix_range</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+reversed the <code>matrix_range</code>.</td>
+</tr>
+</tbody>
+</table>
+<h3>Simple Projections</h3>
+<h4>Description</h4>
+<p>The free <code>subrange</code> functions support the construction
+of matrix ranges.</p>
+<h4>Prototypes</h4>
+<pre><code>
+    template&lt;class M&gt;
+    matrix_range&lt;M&gt; subrange (M &amp;data,
+       M::size_type start1, M::size_type stop1, M::size_type start2, M::size_type, stop2);
+    template&lt;class M&gt;
+    const matrix_range&lt;const M&gt; subrange (const M &amp;data,
+       M::size_type start1, M::size_type stop1, M::size_type start2, M::size_type, stop2);
+</code></pre>
+<h3>Generic Projections</h3>
+<h4>Description</h4>
+<p>The free <code>project</code> functions support the construction
+of matrix ranges. Existing <code>matrix_range</code>'s can be composed with further ranges. The resulting ranges are computed using this existing ranges' <code>compose</code> function.</p>
+<h4>Prototypes</h4>
+<pre><code>
+    template&lt;class M&gt;
+    matrix_range&lt;M&gt; project (M &amp;data, const range &amp;r1, const range &amp;r2);
+    template&lt;class M&gt;
+    const matrix_range&lt;const M&gt; project (const M &amp;data, const range &amp;r1, const range &amp;r2);
+    template&lt;class M&gt;
+    matrix_range&lt;M&gt; project (matrix_range&lt;M&gt; &amp;data, const range &amp;r1, const range &amp;r2);
+    template&lt;class M&gt;
+    const matrix_range&lt;M&gt; project (const matrix_range&lt;M&gt; &amp;data, const range &amp;r1, const range &amp;r2);
+</code></pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_proxy.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>M</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+</ul>
+<h4>Complexity</h4>
+<p>Quadratic depending from the size of the ranges.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            project (m, range (0, 3), range (0, 3)) (i, j) = 3 * i + j;
+    std::cout &lt;&lt; project (m, range (0, 3), range (0, 3)) &lt;&lt; std::endl;
+}
+</pre>
+<h2><a name="matrix_slice"></a>Matrix Slice</h2>
+<h4>Description</h4>
+<p>The templated class <code>matrix_slice&lt;M&gt;</code> allows
+addressing a sliced sub matrix of a matrix.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    matrix_slice&lt;matrix&lt;double&gt; &gt; ms (m, slice (0, 1, 3), slice (0, 1, 3));
+    for (unsigned i = 0; i &lt; ms.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; ms.size2 (); ++ j)
+            ms (i, j) = 3 * i + j;
+    std::cout &lt;&lt; ms &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_proxy.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>M</code></td>
+<td>The type of matrix referenced.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<p>If the specified slices fall outside that of the index range of
+the matrix, then the <code>matrix_slice</code> is not a well formed
+Matrix Expression. That is, access to an element which is outside
+of the matrix is <i>undefined</i>.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;matrix_slice&lt;M&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>matrix_slice (matrix_type &amp;data,<br />
+const slice &amp;s1, const slice &amp;s2)</code></td>
+<td>Constructs a sub matrix.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>matrix_slice &amp;operator = (const matrix_slice
+&amp;ms)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>matrix_slice &amp;assign_temporary (matrix_slice
+&amp;ms)</code></td>
+<td>Assigns a temporary. May change the matrix slice
+<code>ms</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_slice &amp;operator = (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_slice &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the sub matrix. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_slice &amp;operator += (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the sub matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_slice &amp;plus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a matrix expression to the sub matrix. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_slice &amp;operator -= (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the sub matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+matrix_slice &amp;minus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a matrix expression from the sub matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_slice &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the sub matrix with
+a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+matrix_slice &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the sub matrix
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (matrix_slice &amp;ms)</code></td>
+<td>Swaps the contents of the sub matrices.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>matrix_slice</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>matrix_slice</code>.</td>
+</tr>
+</tbody>
+</table>
+<h3>Simple Projections</h3>
+<h4>Description</h4>
+<p>The free <code>subslice</code> functions support the construction
+of matrix slices.</p>
+<h4>Prototypes</h4>
+<pre><code>
+    template&lt;class M&gt;
+    matrix_slice&lt;M&gt; subslice (M &amp;data,
+       M::size_type start1, M::difference_type stride1, M::size_type size1,
+       M::size_type start2, M::difference_type stride2, M::size_type size2);
+    template&lt;class M&gt;
+    const matrix_slice&lt;const M&gt; subslice (const M &amp;data,
+       M::size_type start1, M::difference_type stride1, M::size_type size1,
+       M::size_type start2, M::difference_type stride2, M::size_type size2);
+</code></pre>
+<h3>Generic Projections</h3>
+<h4>Description</h4>
+<p>The free <code>project</code> functions support the construction
+of matrix slices. Existing <code>matrix_slice</code>'s can be composed with further ranges or slices. The resulting slices are computed using this existing slices' <code>compose</code> function.</p>
+<h4>Prototypes</h4>
+<pre><code>
+    template&lt;class M&gt;
+    matrix_slice&lt;M&gt; project (M &amp;data, const slice &amp;s1, const slice &amp;s2);
+    template&lt;class M&gt;
+    const matrix_slice&lt;const M&gt; project (const M &amp;data, const slice &amp;s1, const slice &amp;s2);
+    template&lt;class M&gt;
+    matrix_slice&lt;M&gt; project (matrix_slice&lt;M&gt; &amp;data, const range &amp;r1, const range &amp;r2);
+    template&lt;class M&gt;
+    const matrix_slice&lt;M&gt; project (const matrix_slice&lt;M&gt; &amp;data, const range &amp;r1, const range &amp;r2);
+    template&lt;class M&gt;
+    matrix_slice&lt;M&gt; project (matrix_slice&lt;M&gt; &amp;data, const slice &amp;s1, const slice &amp;s2);
+    template&lt;class M&gt;
+    const matrix_slice&lt;M&gt; project (const matrix_slice&lt;M&gt; &amp;data, const slice &amp;s1, const slice &amp;s2);
+</code></pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_proxy.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>M</code> is a model of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</li>
+</ul>
+<h4>Complexity</h4>
+<p>Quadratic depending from the size of the slices.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/matrix_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            project (m, slice (0, 1, 3), slice (0, 1, 3)) (i, j) = 3 * i + j;
+    std::cout &lt;&lt; project (m, slice (0, 1, 3), slice (0, 1, 3)) &lt;&lt; std::endl;
+}
+</pre>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/matrix_sparse.html b/doc/matrix_sparse.html
new file mode 100644
index 0000000..fb77de4
--- /dev/null
+++ b/doc/matrix_sparse.html
@@ -0,0 +1,983 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Sparse Matrix</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Sparse Matricies</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="mapped_matrix"></a>Mapped Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>mapped_matrix&lt;T, F, A&gt;</code> is
+the base container adaptor for sparse matricies using element maps.
+For a <em>(m xn</em>)-dimensional sparse matrix and <em>0 &lt;= i &lt; m</em>,
+<em>0 &lt;= j &lt; n</em> the non-zero elements
+<em>m</em><sub><em>i, j</em></sub> are mapped via <em>(i x n +
+j)</em> for row major orientation or via <em>(i + j x m)</em> for
+column major orientation to consecutive elements of the associative
+container, i.e. for elements <em>k</em> =
+<em>m</em><sub><em>i</em></sub><sub><sub><em>1</em></sub></sub><sub>
+<em>,j</em></sub><sub><sub><em>1</em></sub></sub>and <em>k + 1 =
+m</em><sub><em>i</em></sub><sub><sub><em>2</em></sub></sub><sub><em>
+,j</em></sub><sub><sub><em>2</em></sub></sub>of the container holds
+<em>i</em><sub><em>1</em></sub> <em>&lt;
+i</em><sub><em>2</em></sub> or <em>(i</em><sub><em>1</em></sub>
+<em>= i</em><sub><em>2</em></sub> and
+<em>j</em><sub><em>1</em></sub> <em>&lt;
+j</em><sub><em>2</em></sub><em>)</em> with row major orientation or
+<em>j</em><sub><em>1</em></sub> <em>&lt;
+j</em><sub><em>2</em></sub> or <em>(j</em><sub><em>1</em></sub>
+<em>= j</em><sub><em>2</em></sub> and
+<em>i</em><sub><em>1</em></sub> <em>&lt;
+i</em><sub><em>2</em></sub><em>)</em> with column major
+orientation.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix_sparse.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    mapped_matrix&lt;double&gt; m (3, 3, 3 * 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+    std::cout &lt;&lt; m &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_sparse.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the mapped matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>Functor describing the storage organization. <a href=
+"#mapped_matrix_1">[1]</a></td>
+<td><code>row_major</code></td>
+</tr>
+<tr>
+<td><code>A</code></td>
+<td>The type of the adapted array. <a href=
+"#mapped_matrix_2">[2]</a></td>
+<td><code>map_std&lt;std::size_t, T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;mapped_matrix&lt;T, F, A&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>mapped_matrix ()</code></td>
+<td>Allocates a <code>mapped_matrix</code> that holds at most zero
+rows of zero elements.</td>
+</tr>
+<tr>
+<td><code>mapped_matrix (size_type size1, size_type2, size_type non_zeros = 0)</code></td>
+<td>Allocates a <code>mapped_matrix</code> that holds at most
+<code>size1</code> rows of <code>size2</code> elements.</td>
+</tr>
+<tr>
+<td><code>mapped_matrix (const mapped_matrix &amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_matrix (size_type non_zeros, const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size1, size_type size2, bool preserve = true)</code></td>
+<td>Reallocates a <code>mapped_matrix</code> to hold at most
+<code>size1</code> rows of <code>size2</code> elements. The
+existing elements of the <code>mapped_matrix</code> are preseved
+when specified.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>mapped_matrix &amp;operator = (const mapped_matrix
+&amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>mapped_matrix &amp;assign_temporary (mapped_matrix
+&amp;m)</code></td>
+<td>Assigns a temporary. May change the mapped matrix
+<code>m</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_matrix &amp;operator = (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_matrix &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the mapped matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_matrix &amp;operator += (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the mapped matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_matrix &amp;plus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a matrix expression to the mapped matrix. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_matrix &amp;operator -= (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the mapped matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_matrix &amp;minus_assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a matrix expression from the mapped matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+mapped_matrix &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the mapped matrix
+with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+mapped_matrix &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the mapped matrix
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (mapped_matrix &amp;m)</code></td>
+<td>Swaps the contents of the mapped matrices.</td>
+</tr>
+<tr>
+<td><code>true_refrence insert_element (size_type i, size_type j, const_reference
+t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>j</code>-th
+element of the <code>i</code>-th row. Duplicates elements are not allowed.</td>
+</tr>
+<tr>
+<td><code>void erase_element (size_type i, size_type j)</code></td>
+<td>Erases the value at the <code>j</code>-th element of the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the mapped matrix.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>mapped_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>mapped_matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="mapped_matrix_1">[1]</a> Supported
+parameters for the storage organization are <code>row_major</code>
+and <code>column_major</code>.</p>
+<p><a name="mapped_matrix_2">[2]</a> Supported
+parameters for the adapted array are
+<code>map_array&lt;std::size_t, T&gt;</code> and
+<code>map_std&lt;std::size_t, T&gt;</code>. The latter is
+equivalent to <code>std::map&lt;std::size_t, T&gt;</code>.</p>
+<h2><a name="compressed_matrix"></a>Compressed Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>compressed_matrix&lt;T, F, IB, IA,
+TA&gt;</code> is the base container adaptor for compressed
+matrices. For a <em>(m x n</em> )-dimensional compressed matrix and
+<em>0 &lt;= i &lt; m</em>, <em>0 &lt;= j &lt; n</em> the non-zero
+elements <em>m</em><sub><em>i, j</em></sub> are mapped via <em>(i x
+n + j)</em> for row major orientation or via <em>(i + j x m)</em>
+for column major orientation to consecutive elements of the index
+and value containers, i.e. for elements <em>k</em> =
+<em>m</em><sub><em>i</em></sub><sub><sub><em>1</em></sub></sub><sub>
+<em>,j</em></sub><sub><sub><em>1</em></sub></sub>and <em>k + 1 =
+m</em><sub><em>i</em></sub><sub><sub><em>2</em></sub></sub><sub><em>
+,j</em></sub><sub><sub><em>2</em></sub></sub>of the container holds
+<em>i</em><sub><em>1</em></sub> <em>&lt;
+i</em><sub><em>2</em></sub> or <em>(i</em><sub><em>1</em></sub>
+<em>= i</em><sub><em>2</em></sub> and
+<em>j</em><sub><em>1</em></sub> <em>&lt;
+j</em><sub><em>2</em></sub><em>)</em> with row major orientation or
+<em>j</em><sub><em>1</em></sub> <em>&lt;
+j</em><sub><em>2</em></sub> or <em>(j</em><sub><em>1</em></sub>
+<em>= j</em><sub><em>2</em></sub> and
+<em>i</em><sub><em>1</em></sub> <em>&lt;
+i</em><sub><em>2</em></sub><em>)</em> with column major
+orientation.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix_sparse.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    compressed_matrix&lt;double&gt; m (3, 3, 3 * 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+    std::cout &lt;&lt; m &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_sparse.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the compressed matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>Functor describing the storage organization. <a href=
+"#compressed_matrix_1">[1]</a></td>
+<td><code>row_major</code></td>
+</tr>
+<tr>
+<td><code>IB</code></td>
+<td>The index base of the compressed vector. <a href=
+"#compressed_matrix_2">[2]</a></td>
+<td><code>0</code></td>
+</tr>
+<tr>
+<td><code>IA</code></td>
+<td>The type of the adapted array for indices. <a href=
+"#compressed_matrix_3">[3]</a></td>
+<td><code>unbounded_array&lt;std::size_t&gt;</code></td>
+</tr>
+<tr>
+<td><code>TA</code></td>
+<td>The type of the adapted array for values. <a href=
+"#compressed_matrix_3">[3]</a></td>
+<td><code>unbounded_array&lt;T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;compressed_matrix&lt;T, F, IB, IA,
+TA&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>compressed_matrix ()</code></td>
+<td>Allocates a <code>compressed_matrix</code> that holds at most
+zero rows of zero elements.</td>
+</tr>
+<tr>
+<td><code>compressed_matrix (size_type size1, size_type2, size_type non_zeros = 0)</code></td>
+<td>Allocates a <code>compressed_matrix</code> that holds at most
+<code>size1</code> rows of <code>size2</code> elements.</td>
+</tr>
+<tr>
+<td><code>compressed_matrix (const compressed_matrix
+&amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_matrix (size_type non_zeros, const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size1, size_type size2, bool preserve = true)</code></td>
+<td>Reallocates a <code>compressed_matrix</code> to hold at most
+<code>size1</code> rows of <code>size2</code> elements. The
+existing elements of the <code>compressed_matrix</code> are
+preseved when specified.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>compressed_matrix &amp;operator = (const
+compressed_matrix &amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>compressed_matrix &amp;assign_temporary
+(compressed_matrix &amp;m)</code></td>
+<td>Assigns a temporary. May change the compressed matrix
+<code>m</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_matrix &amp;operator = (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_matrix &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the compressed matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_matrix &amp;operator += (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the compressed matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_matrix &amp;plus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a matrix expression to the compressed matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_matrix &amp;operator -= (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the compressed matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_matrix &amp;minus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a matrix expression from the compressed matrix. Left
+and right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+compressed_matrix &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the compressed
+matrix with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+compressed_matrix &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the compressed matrix
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (compressed_matrix &amp;m)</code></td>
+<td>Swaps the contents of the compressed matrices.</td>
+</tr>
+<tr>
+<td><code>true_reference insert_element (size_type i, size_type j, const_reference
+t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>j</code>-th
+element of the <code>i</code>-th row. Duplicates elements are not allowed.</td>
+</tr>
+<tr>
+<td><code>void erase_element (size_type i, size_type j)</code></td>
+<td>Erases the value at the <code>j</code>-th element of the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the compressed matrix.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>compressed_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>compressed_matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="compressed_matrix_1">[1]</a>
+Supported parameters for the storage organization are
+<code>row_major</code> and <code>column_major</code>.</p>
+<p><a name="compressed_matrix_2">[2]</a>
+Supported parameters for the index base are <code>0</code> and
+<code>1</code> at least.</p>
+<p><a name="compressed_matrix_3">[3]</a>
+Supported parameters for the adapted array are
+<code>unbounded_array&lt;&gt;</code> ,
+<code>bounded_array&lt;&gt;</code> and
+<code>std::vector&lt;&gt;</code> .</p>
+<h2><a name="coordinate_matrix"></a>Coordinate Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>coordinate_matrix&lt;T, F, IB, IA,
+TA&gt;</code> is the base container adaptor for compressed
+matrices. For a <em>(m x n</em> )-dimensional sorted coordinate
+matrix and <em>0 &lt;= i &lt; m</em>, <em>0 &lt;= j &lt; n</em> the
+non-zero elements <em>m</em><sub><em>i, j</em></sub> are mapped via
+<em>(i x n + j)</em> for row major orientation or via <em>(i + j x
+m)</em> for column major orientation to consecutive elements of the
+index and value containers, i.e. for elements <em>k</em> =
+<em>m</em><sub><em>i</em></sub><sub><sub><em>1</em></sub></sub><sub>
+<em>,j</em></sub><sub><sub><em>1</em></sub></sub>and <em>k + 1 =
+m</em><sub><em>i</em></sub><sub><sub><em>2</em></sub></sub><sub><em>
+,j</em></sub><sub><sub><em>2</em></sub></sub>of the container holds
+<em>i</em><sub><em>1</em></sub> <em>&lt;
+i</em><sub><em>2</em></sub> or <em>(i</em><sub><em>1</em></sub>
+<em>= i</em><sub><em>2</em></sub> and
+<em>j</em><sub><em>1</em></sub> <em>&lt;
+j</em><sub><em>2</em></sub><em>)</em> with row major orientation or
+<em>j</em><sub><em>1</em></sub> <em>&lt;
+j</em><sub><em>2</em></sub> or <em>(j</em><sub><em>1</em></sub>
+<em>= j</em><sub><em>2</em></sub> and
+<em>i</em><sub><em>1</em></sub> <em>&lt;
+i</em><sub><em>2</em></sub><em>)</em> with column major
+orientation.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix_sparse.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    coordinate_matrix&lt;double&gt; m (3, 3, 3 * 3);
+    for (unsigned i = 0; i &lt; m.size1 (); ++ i)
+        for (unsigned j = 0; j &lt; m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+    std::cout &lt;&lt; m &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header matrix_sparse.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the coordinate matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>Functor describing the storage organization. <a href=
+"#coordinate_matrix_1">[1]</a></td>
+<td><code>row_major</code></td>
+</tr>
+<tr>
+<td><code>IB</code></td>
+<td>The index base of the coordinate vector. <a href=
+"#coordinate_matrix_2">[2]</a></td>
+<td><code>0</code></td>
+</tr>
+<tr>
+<td><code>IA</code></td>
+<td>The type of the adapted array for indices. <a href=
+"#coordinate_matrix_3">[3]</a></td>
+<td><code>unbounded_array&lt;std::size_t&gt;</code></td>
+</tr>
+<tr>
+<td><code>TA</code></td>
+<td>The type of the adapted array for values. <a href=
+"#coordinate_matrix_3">[3]</a></td>
+<td><code>unbounded_array&lt;T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;coordinate_matrix&lt;T, F, IB, IA,
+TA&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>coordinate_matrix ()</code></td>
+<td>Allocates a <code>coordinate_matrix</code> that holds at most
+zero rows of zero elements.</td>
+</tr>
+<tr>
+<td><code>coordinate_matrix (size_type size1, size_type2, size_type non_zeros = 0)</code></td>
+<td>Allocates a <code>coordinate_matrix</code> that holds at most
+<code>size1</code> rows of <code>size2</code> elements.</td>
+</tr>
+<tr>
+<td><code>coordinate_matrix (const coordinate_matrix
+&amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_matrix (size_type non_zeros, const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size1, size_type size2, bool preserve = true)</code></td>
+<td>Reallocates a <code>coordinate_matrix</code> to hold at most
+<code>size1</code> rows of <code>size2</code> elements. The
+existing elements of the <code>coordinate_matrix</code> are
+preseved when specified.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>coordinate_matrix &amp;operator = (const
+coordinate_matrix &amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>coordinate_matrix &amp;assign_temporary
+(coordinate_matrix &amp;m)</code></td>
+<td>Assigns a temporary. May change the coordinate matrix
+<code>m</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_matrix &amp;operator = (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_matrix &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the coordinate matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_matrix &amp;operator += (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the coordinate matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_matrix &amp;plus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a matrix expression to the coordinate matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_matrix &amp;operator -= (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the coordinate matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_matrix &amp;minus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a matrix expression from the coordinate matrix. Left
+and right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+coordinate_matrix &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the coordinate
+matrix with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+coordinate_matrix &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the coordinate matrix
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (coordinate_matrix &amp;m)</code></td>
+<td>Swaps the contents of the coordinate matrices.</td>
+</tr>
+<tr>
+<td><code>true_reference insert_element (size_type i, size_type j, const_reference
+t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>j</code>-th
+element of the <code>i</code>-th row. Duplicates elements are not allowed.</td>
+</tr>
+<tr>
+<td><code>void append_element (size_type i, size_type j, const_reference t)</code></td>
+<td>Appends the value <code>t</code> at the <code>j</code>-th element of the <code>i</code>-th row.
+Duplicate elements can be appended to a <code>coordinate_matrix</code>. They are merged into a single
+arithmetically summed element by the <code>sort</code> function.</td>
+</tr>
+<tr>
+<td><code>void erase_element (size_type i, size_type j)</code></td>
+<td>Erases the value at the <code>j</code>-th element of the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the coordinate matrix.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>coordinate_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>coordinate_matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="coordinate_matrix_1">[1]</a>
+Supported parameters for the storage organization are
+<code>row_major</code> and <code>column_major</code>.</p>
+<p><a name="coordinate_matrix_2">[2]</a>
+Supported parameters for the index base are <code>0</code> and
+<code>1</code> at least.</p>
+<p><a name="coordinate_matrix_3">[3]</a>
+Supported parameters for the adapted array are
+<code>unbounded_array&lt;&gt;</code> ,
+<code>bounded_array&lt;&gt;</code> and
+<code>std::vector&lt;&gt;</code> .</p>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/operations_overview.html b/doc/operations_overview.html
new file mode 100644
index 0000000..42d9942
--- /dev/null
+++ b/doc/operations_overview.html
@@ -0,0 +1,261 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta name="GENERATOR" content="Quanta Plus" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>uBLAS operations overview</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Overview of Matrix and Vector Operations</h1>
+<div class="toc" id="toc"></div>
+
+<dl>
+<dt>Contents:</dt>
+<dd><a href="#blas">Basic Linear Algebra</a></dd>
+<dd><a href="#advanced">Advanced Functions</a></dd>
+<dd><a href="#sub">Submatrices, Subvectors</a></dd>
+<dd><a href="#speed">Speed Improvements</a></dd>
+</dl>
+
+<h2>Definitions</h2>
+
+<table style="" summary="notation">
+<tr><td><code>A, B, C</code></td>
+<td> are matrices</td></tr>
+<tr><td><code>u, v, w</code></td> 
+<td>are vectors</td></tr>
+<tr><td><code>i, j, k</code></td> 
+<td>are integer values</td></tr>
+<tr><td><code>t, t1, t2</code></td> 
+<td>are scalar values</td></tr>
+<tr><td><code>r, r1, r2</code></td> 
+<td>are <a href="range.html">ranges</a>, e.g. <code>range(0, 3)</code></td></tr>
+<tr><td><code>s, s1, s2</code></td> 
+<td>are <a href="range.html#slice">slices</a>, e.g. <code>slice(0, 1, 3)</code></td></tr>
+</table>
+
+<h2><a name="blas">Basic Linear Algebra</a></h2>
+
+<h3>standard operations: addition, subtraction, multiplication by a
+scalar</h3>
+
+<pre><code>
+C = A + B; C = A - B; C = -A;
+w = u + v; w = u - v; w = -u;
+C = t * A; C = A * t; C = A / t;
+w = t * u; w = u * t; w = u / t;
+</code></pre>
+
+<h3>computed assignments</h3>
+
+<pre><code>
+C += A; C -= A; 
+w += u; w -= u; 
+C *= t; C /= t; 
+w *= t; w /= t;
+</code></pre>
+
+<h3>inner, outer and other products</h3>
+
+<pre><code>
+t = inner_prod(u, v);
+C = outer_prod(u, v);
+w = prod(A, u); w = prod(u, A); w = prec_prod(A, u); w = prec_prod(u, A);
+C = prod(A, B); C = prec_prod(A, B);
+w = element_prod(u, v); w = element_div(u, v);
+C = element_prod(A, B); C = element_div(A, B);
+</code></pre>
+
+<h3>transformations</h3>
+
+<pre><code>
+w = conj(u); w = real(u); w = imag(u);
+C = trans(A); C = conj(A); C = herm(A); C = real(A); C = imag(A);
+</code></pre>
+
+<h2><a name="advanced">Advanced functions</a></h2>
+
+<h3>norms</h3>
+
+<pre><code>
+t = norm_inf(v); i = index_norm_inf(v);
+t = norm_1(v);   t = norm_2(v); 
+t = norm_inf(A); i = index_norm_inf(A);
+t = norm_1(A);   t = norm_frobenius(A); 
+</code></pre>
+
+<h3>products</h3>
+
+<pre><code>
+axpy_prod(A, u, w, true);  // w = A * u
+axpy_prod(A, u, w, false); // w += A * u
+axpy_prod(u, A, w, true);  // w = trans(A) * u
+axpy_prod(u, A, w, false); // w += trans(A) * u
+axpy_prod(A, B, C, true);  // C = A * B
+axpy_prod(A, B, C, false); // C += A * B
+</code></pre>
+<p><em>Note:</em> The last argument (<code>bool init</code>) of
+<code>axpy_prod</code> is optional. Currently it defaults to
+<code>true</code>, but this may change in the future. Setting the
+<code>init</code> to <code>true</code> is equivalent to calling
+<code>w.clear()</code> before <code>axpy_prod</code>. 
+There are some specialisation for products of compressed matrices that give a
+large speed up compared to <code>prod</code>.</p>
+<pre><code>
+w = block_prod&lt;matrix_type, 64&gt; (A, u); // w = A * u
+w = block_prod&lt;matrix_type, 64&gt; (u, A); // w = trans(A) * u
+C = block_prod&lt;matrix_type, 64&gt; (A, B); // C = A * B
+</code></pre>
+<p><em>Note:</em> The blocksize can be any integer. However, the
+actual speed depends very significantly on the combination of blocksize,
+CPU and compiler. The function <code>block_prod</code> is designed
+for large dense matrices.</p>
+<h3>rank-k updates</h3>
+<pre><code>
+opb_prod(A, B, C, true);  // C = A * B
+opb_prod(A, B, C, false); // C += A * B
+</code></pre>
+<p><em>Note:</em> The last argument (<code>bool init</code>) of
+<code>opb_prod</code> is optional. Currently it defaults to
+<code>true</code>, but this may change in the future. This function
+may give a speedup if <code>A</code> has less columns than rows,
+because the product is computed as a sum of outer products.</p>
+
+<h2><a name="sub">Submatrices, Subvectors</a></h2>
+<p>Accessing submatrices and subvectors via <b>proxies</b> using <code>project</code> functions:</p>
+<pre><code>
+w = project(u, r);         // the subvector of u specifed by the index range r
+w = project(u, s);         // the subvector of u specifed by the index slice s
+C = project(A, r1, r2);    // the submatrix of A specified by the two index ranges r1 and r2
+C = project(A, s1, s2);    // the submatrix of A specified by the two index slices s1 and s2
+w = row(A, i); w = column(A, j);    // a row or column of matrix as a vector
+</code></pre>
+<p>Assigning to submatrices and subvectors via <b>proxies</b> using <code>project</code> functions:</p>
+<pre><code>
+project(u, r) = w;         // assign the subvector of u specifed by the index range r
+project(u, s) = w;         // assign the subvector of u specifed by the index slice s
+project(A, r1, r2) = C;    // assign the submatrix of A specified by the two index ranges r1 and r2
+project(A, s1, s2) = C;    // assign the submatrix of A specified by the two index slices s1 and s2
+row(A, i) = w; column(A, j) = w;    // a row or column of matrix as a vector
+</code></pre>
+<p><em>Note:</em> A range <code>r = range(start, stop)</code>
+contains all indices <code>i</code> with <code>start &lt;= i &lt;
+stop</code>. A slice is something more general. The slice
+<code>s = slice(start, stride, size)</code> contains the indices
+<code>start, start+stride, ..., start+(size-1)*stride</code>. The
+stride can be 0 or negative! If <code>start >= stop</code> for a range
+or <code>size == 0</code> for a slice then it contains no elements.</p>
+<p>Sub-ranges and sub-slices of vectors and matrices can be created directly with the <code>subrange</code> and <code>sublice</code> functions:</p>
+<pre><code>
+w = subrange(u, 0, 2);         // the 2 element subvector of u
+w = subslice(u, 0, 1, 2);      // the 2 element subvector of u
+C = subrange(A, 0,2, 0,3);     // the 2x3 element submatrix of A
+C = subslice(A, 0,1,2, 0,1,3); // the 2x3 element submatrix of A
+subrange(u, 0, 2) = w;         // assign the 2 element subvector of u
+subslice(u, 0, 1, 2) = w;      // assign the 2 element subvector of u
+subrange(A, 0,2, 0,3) = C;     // assign the 2x3 element submatrix of A
+subrange(A, 0,1,2, 0,1,3) = C; // assigne the 2x3 element submatrix of A
+</code></pre>
+<p>There are to more ways to access some matrix elements as a
+vector:</p>
+<pre><code>matrix_vector_range&lt;matrix_type&gt; (A, r1, r2);
+matrix_vector_slice&lt;matrix_type&gt; (A, s1, s2);
+</code></pre>
+<p><em>Note:</em> These matrix proxies take a sequence of elements
+of a matrix and allow you to access these as a vector. In
+particular <code>matrix_vector_slice</code> can do this in a very
+general way. <code>matrix_vector_range</code> is less useful as the
+elements must lie along a diagonal.</p>
+<p><em>Example:</em> To access the first two elements of a sub
+column of a matrix we access the row with a slice with stride 1 and
+the column with a slice with stride 0 thus:<br />
+<code>matrix_vector_slice&lt;matrix_type&gt; (A, slice(0,1,2),
+slice(0,0,2));
+</code></p>
+
+<h2><a name="speed">Speed improvements</a></h2>
+<h3><a name='noalias'>Matrix / Vector assignment</a></h3>
+<p>If you know for sure that the left hand expression and the right
+hand expression have no common storage, then assignment has
+no <em>aliasing</em>. A more efficient assignment can be specified
+in this case:</p>
+<pre><code>noalias(C) = prod(A, B);
+</code></pre>
+<p>This avoids the creation of a temporary matrix that is required in a normal assignment.
+'noalias' assignment requires that the left and right hand side be size conformant.</p>
+
+<h3>Sparse element access</h3>
+<p>The matrix element access function <code>A(i1,i2)</code> or the equivalent vector
+element access functions (<code>v(i) or v[i]</code>) usually create 'sparse element proxies'
+when applied to a sparse matrix or vector. These <em>proxies</em> allow access to elements
+without having to worry about nasty C++ issues where references are invalidated.</p>
+<p>These 'sparse element proxies' can be implemented more efficiently when applied to <code>const</code>
+objects.
+Sadly in C++ there is no way to distinguish between an element access on the left and right hand side of
+an assignment. Most often elements on the right hand side will not be changed and therefore it would
+be better to use the <code>const</code> proxies. We can do this by making the matrix or vector
+<code>const</code> before accessing it's elements. For example:</p>
+<pre><code>value = const_cast&lt;const VEC&gt;(v)[i];   // VEC is the type of V
+</code></pre>
+<p>If more then one element needs to be accessed <code>const_iterator</code>'s should be used
+in preference to <code>iterator</code>'s for the same reason. For the more daring 'sparse element proxies'
+can be completely turned off in uBLAS by defining the configuration macro <code>BOOST_UBLAS_NO_ELEMENT_PROXIES</code>.
+</p>
+
+
+<h3>Controlling the complexity of nested products</h3>
+
+<p>What is the  complexity (the number of add and multiply operations) required to compute the following?
+</p>
+<pre>
+ R = prod(A, prod(B,C)); 
+</pre>
+<p>Firstly the complexity depends on matrix size. Also since prod is transitive (not commutative)
+the bracket order affects the complexity.
+</p>
+<p>uBLAS evaluates expressions without matrix or vector temporaries and honours
+the bracketing structure. However avoiding temporaries for nested product unnecessarly increases the complexity.
+Conversly by explictly using temporary matrices the complexity of a nested product can be reduced.
+</p>
+<p>uBLAS provides 3 alternative syntaxes for this purpose:
+</p>
+<pre>
+ temp_type T = prod(B,C); R = prod(A,T);   // Preferable if T is preallocated
+</pre>
+<pre>
+ prod(A, temp_type(prod(B,C));
+</pre>
+<pre>
+ prod(A, prod&lt;temp_type&gt;(B,C));
+</pre>
+<p>The 'temp_type' is important. Given A,B,C are all of the same type. Say
+matrix&lt;float&gt;, the choice is easy. However if the value_type is mixed (int with float or double)
+or the matrix type is mixed (sparse with symmetric) the best solution is not so obvious. It is up to you! It
+depends on numerical properties of A and the result of the prod(B,C).
+</p>
+
+<hr />
+<p>Copyright (&copy;) 2000-2007 Joerg Walter, Mathias Koch, Gunter
+Winkler, Michael Stevens<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/options.html b/doc/options.html
new file mode 100644
index 0000000..2b9e6f2
--- /dev/null
+++ b/doc/options.html
@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" >
+<head>
+<meta name="generator" content="HTML Tidy for Linux (vers 6 November 2007), see www.w3.org" />
+<!-- tidy options: -w 120 -asxhtml -clean - - vertical-space yes -f index.html.err -m index.html -->
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Boost Basic Linear Algebra - Configuration Options</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" alt="logo"/>Boost Basic Linear Algebra - Configuration Options</h1>
+<div class="toc" id="toc"></div>
+
+<div class="navigation">
+<a href="index.html">back to uBLAS home</a>
+</div>
+
+<h2>NDEBUG</h2> 
+
+<p><strong>Make sure you define NDEBUG</strong> The only way uBLAS
+knows you want a release configuration is to check if you have defined
+NDEBUG. If you don't it assumes you want a debug configuration and
+adds a lot of very useful runtime check. However these are very slow!
+</p>
+
+
+<h2>BOOST_UBLAS_MOVE_SEMANTICS</h2>
+
+<p class="credit">The patch and description was provided by Nasos Iliopoulos.</p>
+
+<p>An immediate effect of this option is the elimination of the need
+for noalias in types <tt>vector&lt;T&gt;</tt> and <tt>matrix&lt;T&gt;</tt>,
+when assigned to the same type. This option doesn't have an effect on
+bounded and c types. Although it is rare, not all compilers support copy
+elision (that allows for move semantics), so a test must be performed to
+make sure that there is a benefit when it is enabled. A small
+demonstration and test can be found in
+<a href="../test/manual/test_move_semantics.cpp"><tt>test_move_semantics.cpp</tt></a></p>
+
+<p>
+In the <a href="../test/manual/test_move_semantics.cpp">test
+example</a> two tests are defined, one for vectors and one for
+matrices. The aim of this example is to print the pointers of the
+storage of each of the containers, before and after the assignment to
+a temporary object. When move semantics are enabled, the
+<tt>vector&lt;T&gt;</tt> and <tt>matrix&lt;T&gt;</tt> storage is moved
+from the temporary and no copy is performed.
+</p>
+
+<p>
+If move semantics are supported by your compiler you will get an output like the following:
+</p>
+<pre class="screen">
+matrix&lt;double&gt; --------------------------------------------------------------------
+Temporary pointer r: 0x94790c0
+Pointer (must be equal to temp. pointer if move semantics are enabled) : 0x94790c0
+</pre>
+
+<p>Notes:</p>
+<ul>
+<li>It should be no surprise to see matrices and vectors been passed
+by VALUE, the compiler takes care and either moves (if the underlying
+code does not modify the object), or copies (if the underlying code
+modifies the object).
+</li>
+<li>There might be some space for some improvements (like clearing the
+data, before swaping)
+</li>
+<li>Move semantics don't eliminate temporaries. They rather move their
+storage around so no copies are performed.
+</li>
+<li>MSVC does no implement Named Return Value Optimization in debug
+mode. So if you build in debug with this compiler you might get <a
+href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=483229"
+target="_blank">different behaviour</a> than a release build.
+</li>
+<li>Enabling move semantics is done via #define BOOST_UBLAS_MOVE_SEMANTICS.
+</li>
+<li>There is plenty of room for optimizations when c++0x standard is
+out, taking advantage of rvalue references. (I have a sweet vector
+implementation using that).
+</li>
+<li>If you enable move semantics and your compiler does not support
+them, the operation will just be as passing by const reference.
+</li>
+</ul>
+
+<p>Interesting links</p>
+<ul>
+<li> <a href="http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/" target="_blank">Want Speed? Pass by Value.</a>
+</li>
+<li> <a href="http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx" target="_blank">Rvalue References: C++0x Features in VC10, Part 2</a>
+</li>
+<li> <a href="http://cpp-next.com/archive/2009/09/move-it-with-rvalue-references/" target="_blank">Move It With Rvalue References</a>
+</li>
+</ul>
+
+<h2>BOOST_UBLAS_CHECK_ENABLE</h2>
+
+<p>When BOOST_UBLAS_CHECK_ENABLE is defined then all index and
+parameter checks are enabled. This is enabled in debug mode and
+disabled in release mode.
+</p>
+
+<h2>BOOST_UBLAS_TYPE_CHECK</h2>
+
+<p>When BOOST_UBLAS_TYPE_CHECK is enabled then all possibly expensive
+structure checks are enabled. If this is not desireable then use
+<tt>#define BOOST_UBLAS_TYPE_CHECK 0</tt> before including any uBLAS
+header. The define BOOST_UBLAS_TYPE_CHECK_EPSILON can be used to
+control the acceptable tolerance, see
+<tt>detail/matrix_assign.hpp</tt> for implementation details of this
+check.
+</p>
+
+<h2>BOOST_UBLAS_USE_LONG_DOUBLE</h2> 
+
+<p>Enable uBLAS expressions that involve containers of 'long double'</p>
+
+<h2>BOOST_UBLAS_USE_INTERVAL</h2>
+
+<p>Enable uBLAS expressions that involve containers of 'boost::numeric::interval' types</p>
+
+<h2>Configuring uBLAS with Macros</h2>
+
+<p>Many macro's appear in ublas/config.hpp and elsewhere. Hopefully in the future some of these will disappear!
+They fall into 4 groups:
+</p>
+<ul>
+<li> Automatically set by 'boost/numeric/ublas/config.hpp' based on
+NDEBUG. Makes the distinction between debug (safe) and release (fast)
+mode. Similar to STLport
+<ul>
+<li> <i>Release</i> mode (NDEBUG defined)
+<ul>
+<li> BOOST_UBLAS_INLINE <i>Compiler dependant definition to control
+function inlining.</i> </li><li> BOOST_UBLAS_USE_FAST_SAME </li></ul>
+</li><li> <i>Debug</i> mode
+<ul>
+<li> BOOST_UBLAS_CHECK_ENABLE <i>Enable checking of indexs, iterators
+and parameters. Prevents out of bound access etc.</i> </li><li>
+BOOST_UBLAS_TYPE_CHECK <i>Enable additional checks for the results of
+expressions using non dense types. Picks up runtime error such as the
+assignment of a numerically non-symmetric matrix to
+symmertic_matrix. Use <tt>#define BOOST_UBLAS_TYPE_CHECK 0</tt> to
+disable expensive numeric type checks.</i> (Note: "structure check"
+would be a much better name.)  </li><li>
+BOOST_UBLAS_TYPE_CHECK_EPSILON <i>default: sqrt(epsilon), controls how
+large the difference between the expected result and the computed
+result may become. Increase this value if you are going to use near
+singular or badly scaled matrices. Please, refer to
+<tt>detail/matrix_assign.hpp</tt> for implementation of these type
+checks.</i> </li></ul> </li></ul>
+</li>
+<li> Automatically set by 'boost/numeric/ublas/config.hpp' based on
+compiler and boost/config.hpp macro's. Augments the compiler
+deficiency workarounds already supplied by boost/config.hpp
+<ul>
+<li> BOOST_UBLAS_NO_NESTED_CLASS_RELATION <i>A particularly nasty
+problem with VC7.1 Requires that uBLAS and the user use begin(it)
+rather then it.begin()</i> </li><li> BOOST_UBLAS_NO_SMART_PROXIES
+<i>Disable the automatic propagation of 'constantness' to
+proxies. Smart proxies automatically determine if the underling
+container they reference is constant or not. They adjust there
+definition of iterators and container access to reflect this
+constantness.</i> </li></ul>
+</li>
+<li> For use by uBLAS authors to test implementation methods. Preset
+in config.hpp
+<ul>
+<li> BOOST_UBLAS_USE_INVARIANT_HOISTING </li><li>
+BOOST_UBLAS_USE_INDEXING </li><li> BOOST_UBLAS_USE_INDEXED_ITERATOR
+</li><li> BOOST_UBLAS_NON_CONFORMANT_PROXIES <i>Gappy containers may
+be non-conformant, that is contain elements at different
+indices. Assigning between proxies (vector ranges for example) of
+these containers is difficult as the LHS may need insert new
+elements. This is slow.</i> </li><li> BOOST_UBLAS_USE_DUFF_DEVICE
+<i>Near useless on all platforms (see GCC's -funroll-loops)</i>
+
+</li></ul>
+</li>
+<li> User options. Can be predefined by user before including any
+uBLAS headers. They may also be automatically defined for some
+compilers to work around compile bugs.
+<ul>
+<li> BOOST_UBLAS_USE_LONG_DOUBLE <i>Enable uBLAS expressions that
+involve containers of 'long double'</i> </li><li>
+BOOST_UBLAS_USE_INTERVAL <i>Enable uBLAS expressions that involve
+containers of 'boost::numeric::interval' types</i> </li><li>
+BOOST_UBLAS_SIMPLE_ET_DEBUG <i>In order to simplify debugging is is
+possible to simplify expression templateso they are restricted to a
+single operation</i>
+
+</li><li> BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS <i> enable automatic
+conversion from proxy class to matrix expression </i> </li><li>
+BOOST_UBLAS_NO_ELEMENT_PROXIES <i>Disables the use of element proxies
+for gappy types.</i> </li><li> <i>The Gappy types (sparse, coordinate,
+compressed) store non-zero elements in their own containers. When new
+non-zero elements are assigned they must rearrange these
+containers. This invalidates references, iterators or pointers to
+these elements. This can happen at some surprising times such as the
+expression "a [1] = a [0] = 1;". Element proxies guarantee all such
+expressions will work as expected. However they bring their own
+restrictions and efficiency problems. For example as of Boost 1.30.0
+they prevent the assignment of elements between different types.</i>
+</li>
+<li> BOOST_UBLAS_REFERENCE_CONST_MEMBER <i>Enable to allow refernces
+to be returned to fixed (zero or one) elements of triangular or banded
+matrices</i>
+
+</li><li> BOOST_UBLAS_NO_EXCEPTIONS <i>Disable the use exceptions of
+uBLAS internal checks and error conditions. BOOST_NO_EXCEPTIONS has
+same effect.</i> 
+</li> 
+<li> BOOST_UBLAS_SINGULAR_CHECK <i>Check the for singularity in triangular solve() functions</i></li>
+</ul>
+</li>
+</ul>
+
+<hr />
+<div id="copyright">
+ <p>Copyright (&copy;) 2000-2009 Joerg Walter, Mathias Koch, Gunter Winkler<br />
+   Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+ </p>
+</div>
+<div id="revision">
+<p>
+<!-- Created: Wed Sep 16 21:19:20 CEST 2009 -->
+<!-- hhmts start -->
+Last modified: Wed Sep 16 23:16:45 CEST 2009
+<!-- hhmts end -->
+</p>
+</div>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/overview.html b/doc/overview.html
new file mode 100644
index 0000000..1ce347d
--- /dev/null
+++ b/doc/overview.html
@@ -0,0 +1,965 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content="HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>uBLAS Overview</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" alt="logo"/>uBLAS Overview</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="rationale">Rationale</h2>
+<p><cite>It would be nice if every kind of numeric software could
+be written in C++ without loss of efficiency, but unless something
+can be found that achieves this without compromising the C++ type
+system it may be preferable to rely on Fortran, assembler or
+architecture-specific extensions (Bjarne Stroustrup).</cite></p>
+<p>This C++ library is directed towards scientific computing on the
+level of basic linear algebra constructions with matrices and
+vectors and their corresponding abstract operations. The primary
+design goals were:</p>
+<ul type="disc">
+<li>mathematical notation</li>
+<li>efficiency</li>
+<li>functionality</li>
+<li>compatibility</li>
+</ul>
+<p>Another intention was to evaluate, if the abstraction penalty
+resulting from the use of such matrix and vector classes is
+acceptable.</p>
+<h2>Resources</h2>
+<p>The development of this library was guided by a couple of
+similar efforts:</p>
+<ul type="disc">
+<li><a href="http://www.netlib.org/blas/index.html">BLAS</a> by
+Jack Dongarra et al.</li>
+<li><a href="http://www.oonumerics.org/blitz/">Blitz++</a> by Todd
+Veldhuizen</li>
+<li><a href="http://acts.nersc.gov/pooma/">POOMA</a> by Scott
+Haney et al.</li>
+<li><a href="http://www.lsc.nd.edu/research/mtl/">MTL</a> by Jeremy
+Siek et al.</li>
+</ul>
+<p>BLAS seems to be the most widely used library for basic linear
+algebra constructions, so it could be called a de-facto standard.
+Its interface is procedural, the individual functions are somewhat
+abstracted from simple linear algebra operations. Due to the fact
+that is has been implemented using Fortran and its optimizations,
+it also seems to be one of the fastest libraries available. As we
+decided to design and implement our library in an object-oriented
+way, the technical approaches are distinct. However anyone should
+be able to express BLAS abstractions in terms of our library
+operators and to compare the efficiency of the implementations.</p>
+<p>Blitz++ is an impressive library implemented in C++. Its main
+design seems to be oriented towards multidimensional arrays and
+their associated operators including tensors. The author of Blitz++
+states, that the library achieves performance on par or better than
+corresponding Fortran code due to his implementation technique
+using expression templates and template metaprograms. However we
+see some reasons, to develop an own design and implementation
+approach. We do not know whether anybody tries to implement
+traditional linear algebra and other numerical algorithms using
+Blitz++. We also presume that even today Blitz++ needs the most
+advanced C++ compiler technology due to its implementation idioms.
+On the other hand, Blitz++ convinced us, that the use of expression
+templates is mandatory to reduce the abstraction penalty to an
+acceptable limit.</p>
+<p>POOMA's design goals seem to parallel Blitz++'s in many parts .
+It extends Blitz++'s concepts with classes from the domains of
+partial differential equations and theoretical physics. The
+implementation supports even parallel architectures.</p>
+<p>MTL is another approach supporting basic linear algebra
+operations in C++. Its design mainly seems to be influenced by BLAS
+and the C++ Standard Template Library. We share the insight that a
+linear algebra library has to provide functionality comparable to
+BLAS. On the other hand we think, that the concepts of the C++
+standard library have not yet been proven to support numerical
+computations as needed. As another difference MTL currently does
+not seem to use expression templates. This may result in one of two
+consequences: a possible loss of expressiveness or a possible loss
+of performance.</p>
+<h2>Concepts</h2>
+<h3>Mathematical Notation</h3>
+<p>The usage of mathematical notation may ease the development of
+scientific algorithms. So a C++ library implementing basic linear
+algebra concepts carefully should overload selected C++ operators
+on matrix and vector classes.</p>
+<p>We decided to use operator overloading for the following
+primitives:</p>
+<table border="1" summary="operators">
+<tbody>
+<tr>
+<th align="left">Description</th>
+<th align="left">Operator</th>
+</tr>
+<tr>
+<td>Indexing of vectors and matrices</td>
+<td><code>vector::operator(size_t i);<br />
+matrix::operator(size_t i, size_t j);</code></td>
+</tr>
+<tr>
+<td>Assignment of vectors and matrices</td>
+<td><code>vector::operator = (const vector_expression &amp;);<br />
+vector::operator += (const vector_expression &amp;);<br />
+vector::operator -= (const vector_expression &amp;);<br />
+vector::operator *= (const scalar_expression &amp;);<br />
+matrix::operator = (const matrix_expression &amp;);<br />
+matrix::operator += (const matrix_expression &amp;);<br />
+matrix::operator -= (const matrix_expression &amp;);<br />
+matrix::operator *= (const scalar_expression &amp;);</code></td>
+</tr>
+<tr>
+<td>Unary operations on vectors and matrices</td>
+<td><code>vector_expression operator - (const vector_expression
+&amp;);<br />
+matrix_expression operator - (const matrix_expression
+&amp;);</code></td>
+</tr>
+<tr>
+<td>Binary operations on vectors and matrices</td>
+<td><code>vector_expression operator + (const vector_expression
+&amp;, const vector_expression &amp;);<br />
+vector_expression operator - (const vector_expression &amp;, const
+vector_expression &amp;);<br />
+matrix_expression operator + (const matrix_expression &amp;, const
+matrix_expression &amp;);<br />
+matrix_expression operator - (const matrix_expression &amp;, const
+matrix_expression &amp;);</code></td>
+</tr>
+<tr>
+<td>Multiplication of vectors and matrices with a scalar</td>
+<td><code>vector_expression operator * (const scalar_expression
+&amp;, const vector_expression &amp;);<br />
+vector_expression operator * (const vector_expression &amp;, const
+scalar_expression &amp;);<br />
+matrix_expression operator * (const scalar_expression &amp;, const
+matrix_expression &amp;);<br />
+matrix_expression operator * (const matrix_expression &amp;, const
+scalar_expression &amp;);</code></td>
+</tr>
+</tbody>
+</table>
+<p>We decided to use no operator overloading for the following
+other primitives:</p>
+<table border="1" summary="functions">
+<tbody>
+<tr>
+<th align="left">Description</th>
+<th align="left">Function</th>
+</tr>
+<tr>
+<td>Left multiplication of vectors with a matrix</td>
+<td><code>vector_expression
+prod&lt;</code><code><em>vector_type</em></code> <code>&gt; (const
+matrix_expression &amp;, const vector_expression &amp;);<br />
+vector_expression prod (const matrix_expression &amp;, const
+vector_expression &amp;);</code></td>
+</tr>
+<tr>
+<td>Right multiplication of vectors with a matrix</td>
+<td><code>vector_expression
+prod&lt;</code><code><em>vector_type</em></code> <code>&gt; (const
+vector_expression &amp;, const matrix_expression &amp;);<br />
+vector_expression prod (const vector_expression &amp;, const
+matrix_expression &amp;);<br /></code></td>
+</tr>
+<tr>
+<td>Multiplication of matrices</td>
+<td><code>matrix_expression
+prod&lt;</code><code><em>matrix_type</em></code> <code>&gt; (const
+matrix_expression &amp;, const matrix_expression &amp;);<br />
+matrix_expression prod (const matrix_expression &amp;, const
+matrix_expression &amp;);</code></td>
+</tr>
+<tr>
+<td>Inner product of vectors</td>
+<td><code>scalar_expression inner_prod (const vector_expression
+&amp;, const vector_expression &amp;);</code></td>
+</tr>
+<tr>
+<td>Outer product of vectors</td>
+<td><code>matrix_expression outer_prod (const vector_expression
+&amp;, const vector_expression &amp;);</code></td>
+</tr>
+<tr>
+<td>Transpose of a matrix</td>
+<td><code>matrix_expression trans (const matrix_expression
+&amp;);</code></td>
+</tr>
+</tbody>
+</table>
+<h3>Efficiency</h3>
+<p>To achieve the goal of efficiency for numerical computing, one
+has to overcome two difficulties in formulating abstractions with
+C++, namely temporaries and virtual function calls. Expression
+templates solve these problems, but tend to slow down compilation
+times.</p>
+<h4>Eliminating Temporaries</h4>
+<p>Abstract formulas on vectors and matrices normally compose a
+couple of unary and binary operations. The conventional way of
+evaluating such a formula is first to evaluate every leaf operation
+of a composition into a temporary and next to evaluate the
+composite resulting in another temporary. This method is expensive
+in terms of time especially for small and space especially for
+large vectors and matrices. The approach to solve this problem is
+to use lazy evaluation as known from modern functional programming
+languages. The principle of this approach is to evaluate a complex
+expression element wise and to assign it directly to the
+target.</p>
+<p>Two interesting and dangerous facts result:</p>
+<h4>Aliases</h4>
+<p>One may get serious side effects using element wise
+evaluation on vectors or matrices. Consider the matrix vector
+product <em>x = A x</em>. Evaluation of
+<em>A</em><sub><em>1</em></sub><em>x</em> and assignment to
+<em>x</em><sub><em>1</em></sub> changes the right hand side, so
+that the evaluation of <em>A</em><sub><em>2</em></sub><em>x</em>
+returns a wrong result. In this case there are <strong>aliases</strong> of the elements 
+<em>x</em><sub><em>n</em></sub> on both the left and right hand side of the assignment.</p>
+<p>Our solution for this problem is to
+evaluate the right hand side of an assignment into a temporary and
+then to assign this temporary to the left hand side. To allow
+further optimizations, we provide a corresponding member function
+for every assignment operator and also a 
+<a href="operations_overview.html#noalias"> <code>noalias</code> syntax.</a>
+By using this syntax a programmer can confirm, that the left and right hand sides of an
+assignment are independent, so that element wise evaluation and
+direct assignment to the target is safe.</p>
+<h4>Complexity</h4>
+<p>The computational complexity may be unexpectedly large under certain
+cirumstances. Consider the chained matrix vector product <em>A (B
+x)</em>. Conventional evaluation of <em>A (B x)</em> is quadratic.
+Deferred evaluation of <em>B x</em><sub><em>i</em></sub> is linear.
+As every element <em>B x</em><sub><em>i</em></sub> is needed
+linearly depending of the size, a completely deferred evaluation of
+the chained matrix vector product <em>A (B x)</em> is cubic. In
+such cases one needs to reintroduce temporaries in the
+expression.</p>
+<h4>Eliminating Virtual Function Calls</h4>
+<p>Lazy expression evaluation normally leads to the definition of a
+class hierarchy of terms. This results in the usage of dynamic
+polymorphism to access single elements of vectors and matrices,
+which is also known to be expensive in terms of time. A solution
+was found a couple of years ago independently by David Vandervoorde
+and Todd Veldhuizen and is commonly called expression templates.
+Expression templates contain lazy evaluation and replace dynamic
+polymorphism with static, i.e. compile time polymorphism.
+Expression templates heavily depend on the famous Barton-Nackman
+trick, also coined 'curiously defined recursive templates' by Jim
+Coplien.</p>
+<p>Expression templates form the base of our implementation.</p>
+<h4>Compilation times</h4>
+<p>It is also a well known fact, that expression templates
+challenge currently available compilers. We were able to
+significantly reduce the amount of needed expression templates
+using the Barton-Nackman trick consequently.</p>
+<p>We also decided to support a dual conventional implementation
+(i.e. not using expression templates) with extensive bounds and
+type checking of vector and matrix operations to support the
+development cycle. Switching from debug mode to release mode is
+controlled by the <code>NDEBUG</code> preprocessor symbol of
+<code>&lt;cassert&gt;</code>.</p>
+
+<h2><a name="functionality">Functionality</h2>
+
+<p>Every C++ library supporting linear algebra will be measured
+against the long-standing Fortran package BLAS. We now describe how
+BLAS calls may be mapped onto our classes.</p>
+
+<p>The page <a href="operations_overview.html">Overview of Matrix and Vector Operations</a>
+gives a short summary of the most used operations on vectors and
+matrices.</p>
+
+<h4>Blas Level 1</h4>
+<table border="1" summary="level 1 blas">
+<tbody>
+<tr>
+<th align="left">BLAS Call</th>
+<th align="left">Mapped Library Expression</th>
+<th align="left">Mathematical Description</th>
+<th align="left">Comment</th>
+</tr>
+<tr>
+<td><code>sasum</code> OR <code>dasum</code></td>
+<td><code>norm_1 (x)</code></td>
+<td><em>sum |x<sub>i</sub>|</em></td>
+<td>Computes the <em>l<sub>1</sub></em> (sum) norm of a real vector.</td>
+</tr>
+<tr>
+<td><code>scasum</code> OR <code>dzasum</code></td>
+<td><em><code>real (sum (v)) + imag (sum (v))</code></em></td>
+<td><em>sum re(x<sub>i</sub>) + sum im(x<sub>i</sub>)</em></td>
+<td>Computes the sum of elements of a complex vector.</td>
+</tr>
+<tr>
+<td><code>_nrm2</code></td>
+<td><code>norm_2 (x)</code></td>
+<td><em>sqrt (sum
+|x</em><sub><em>i</em></sub>|<sup><em>2</em></sup> <em>)</em></td>
+<td>Computes the <em>l<sub>2</sub></em> (euclidean) norm of a vector.</td>
+</tr>
+<tr>
+<td><code>i_amax</code></td>
+<td><code>norm_inf (x)<br />
+index_norm_inf (x)</code></td>
+<td><em>max |x</em><sub><em>i</em></sub><em>|</em></td>
+<td>Computes the <em>l<sub>inf</sub></em> (maximum) norm of a vector.<br />
+BLAS computes the index of the first element having this
+value.</td>
+</tr>
+<tr>
+<td><code>_dot<br />
+_dotu<br />
+_dotc</code></td>
+<td><code>inner_prod (x, y)</code>or<code><br />
+inner_prod (conj (x), y)</code></td>
+<td><em>x</em><sup><em>T</em></sup> <em>y</em> or<br />
+<em>x</em><sup><em>H</em></sup> <em>y</em></td>
+<td>Computes the inner product of two vectors.<br />
+BLAS implements certain loop unrollment.</td>
+</tr>
+<tr>
+<td><code>dsdot<br />
+sdsdot</code></td>
+<td><code>a + prec_inner_prod (x, y)</code></td>
+<td><em>a + x</em><sup><em>T</em></sup> <em>y</em></td>
+<td>Computes the inner product in double precision.</td>
+</tr>
+<tr>
+<td><code>_copy</code></td>
+<td><code>x = y<br />
+y.assign (x)</code></td>
+<td><em>x &lt;- y</em></td>
+<td>Copies one vector to another.<br />
+BLAS implements certain loop unrollment.</td>
+</tr>
+<tr>
+<td><code>_swap</code></td>
+<td><code>swap (x, y)</code></td>
+<td><em>x &lt;-&gt; y</em></td>
+<td>Swaps two vectors.<br />
+BLAS implements certain loop unrollment.</td>
+</tr>
+<tr>
+<td><code>_scal<br />
+csscal<br />
+zdscal</code></td>
+<td><code>x *= a</code></td>
+<td><em>x &lt;- a x</em></td>
+<td>Scales a vector.<br />
+BLAS implements certain loop unrollment.</td>
+</tr>
+<tr>
+<td><code>_axpy</code></td>
+<td><code>y += a * x</code></td>
+<td><em>y &lt;- a x + y</em></td>
+<td>Adds a scaled vector.<br />
+BLAS implements certain loop unrollment.</td>
+</tr>
+<tr>
+<td><code>_rot<br />
+_rotm<br />
+csrot<br />
+zdrot</code></td>
+<td><code>t.assign (a * x + b * y),<br />
+y.assign (- b * x + a * y),<br />
+x.assign (t)</code></td>
+<td><em>(x, y) &lt;- (a x + b y, -b x + a y)</em></td>
+<td>Applies a plane rotation.</td>
+</tr>
+<tr>
+<td><code>_rotg<br />
+_rotmg</code></td>
+<td>&nbsp;</td>
+<td><em>(a, b) &lt;-<br />
+&nbsp; (? a / sqrt (a</em><sup><em>2</em></sup> +
+<em>b</em><sup><em>2</em></sup><em>),<br />
+&nbsp; &nbsp; ? b / sqrt (a</em><sup><em>2</em></sup> +
+<em>b</em><sup><em>2</em></sup><em>))</em> or<em><br />
+(1, 0) &lt;- (0, 0)</em></td>
+<td>Constructs a plane rotation.</td>
+</tr>
+</tbody>
+</table>
+<h4>Blas Level 2</h4>
+<table border="1" summary="level 2 blas">
+<tbody>
+<tr>
+<th align="left">BLAS Call</th>
+<th align="left">Mapped Library Expression</th>
+<th align="left">Mathematical Description</th>
+<th align="left">Comment</th>
+</tr>
+<tr>
+<td><code>_t_mv</code></td>
+<td><code>x = prod (A, x)</code> or<code><br />
+x = prod (trans (A), x)</code> or<code><br />
+x = prod (herm (A), x)</code></td>
+<td><em>x &lt;- A x</em> or<em><br />
+x &lt;- A</em><sup><em>T</em></sup> <em>x</em> or<em><br />
+x &lt;- A</em><sup><em>H</em></sup> <em>x</em></td>
+<td>Computes the product of a matrix with a vector.</td>
+</tr>
+<tr>
+<td><code>_t_sv</code></td>
+<td><code>y = solve (A, x, tag)</code> or<br />
+<code>inplace_solve (A, x, tag)</code> or<br />
+<code>y = solve (trans (A), x, tag)</code> or<br />
+<code>inplace_solve (trans (A), x, tag)</code> or<br />
+<code>y = solve (herm (A), x, tag)</code>or<br />
+<code>inplace_solve (herm (A), x, tag)</code></td>
+<!-- TODO: replace nested sub/sup -->
+<td><em>y &lt;- A</em><sup><em>-1</em></sup> <em>x</em>
+or<em><br />
+x &lt;- A</em><sup><em>-1</em></sup> <em>x</em> or<em><br />
+y &lt;-
+A</em><sup><em>T</em></sup><sup><sup><em>-1</em></sup></sup>
+<em>x</em> or<em><br />
+x &lt;-
+A</em><sup><em>T</em></sup><sup><sup><em>-1</em></sup></sup>
+<em>x</em> or<em><br />
+y &lt;-
+A</em><sup><em>H</em></sup><sup><sup><em>-1</em></sup></sup>
+<em>x</em> or<em><br />
+x &lt;-
+A</em><sup><em>H</em></sup><sup><sup><em>-1</em></sup></sup>
+<em>x</em></td>
+<td>Solves a system of linear equations with triangular form, i.e.
+<em>A</em> is triangular.</td>
+</tr>
+<tr>
+<td><code>_g_mv<br />
+_s_mv<br />
+_h_mv</code></td>
+<td><code>y = a * prod (A, x) + b * y</code> or<code><br />
+y = a * prod (trans (A), x) + b * y</code> or<code><br />
+y = a * prod (herm (A), x) + b * y</code></td>
+<td><em>y &lt;- a A x + b y</em> or<em><br />
+y &lt;- a A</em><sup><em>T</em></sup> <em>x + b y<br />
+y &lt;- a A</em><sup><em>H</em></sup> <em>x + b y</em></td>
+<td>Adds the scaled product of a matrix with a vector.</td>
+</tr>
+<tr>
+<td><code>_g_r<br />
+_g_ru<br />
+_g_rc</code></td>
+<td><code>A += a * outer_prod (x, y)</code> or<code><br />
+A += a * outer_prod (x, conj (y))</code></td>
+<td><em>A &lt;- a x y</em><sup><em>T</em></sup> <em>+ A</em>
+or<em><br />
+A &lt;- a x y</em><sup><em>H</em></sup> <em>+ A</em></td>
+<td>Performs a rank <em>1</em> update.</td>
+</tr>
+<tr>
+<td><code>_s_r<br />
+_h_r</code></td>
+<td><code>A += a * outer_prod (x, x)</code> or<code><br />
+A += a * outer_prod (x, conj (x))</code></td>
+<td><em>A &lt;- a x x</em><sup><em>T</em></sup> <em>+ A</em>
+or<em><br />
+A &lt;- a x x</em><sup><em>H</em></sup> <em>+ A</em></td>
+<td>Performs a symmetric or hermitian rank <em>1</em> update.</td>
+</tr>
+<tr>
+<td><code>_s_r2<br />
+_h_r2</code></td>
+<td><code>A += a * outer_prod (x, y) +<br />
+&nbsp;a * outer_prod (y, x))</code> or<code><br />
+A += a * outer_prod (x, conj (y)) +<br />
+&nbsp;conj (a) * outer_prod (y, conj (x)))</code></td>
+<td><em>A &lt;- a x y</em><sup><em>T</em></sup> <em>+ a y
+x</em><sup><em>T</em></sup> <em>+ A</em> or<em><br />
+A &lt;- a x y</em><sup><em>H</em></sup> <em>+
+a</em><sup><em>-</em></sup> <em>y x</em><sup><em>H</em></sup> <em>+
+A</em></td>
+<td>Performs a symmetric or hermitian rank <em>2</em> update.</td>
+</tr>
+</tbody>
+</table>
+<h4>Blas Level 3</h4>
+<table border="1" summary="level 3 blas">
+<tbody>
+<tr>
+<th align="left">BLAS Call</th>
+<th align="left">Mapped Library Expression</th>
+<th align="left">Mathematical Description</th>
+<th align="left">Comment</th>
+</tr>
+<tr>
+<td><code>_t_mm</code></td>
+<td><code>B = a * prod (A, B)</code> or<br />
+<code>B = a * prod (trans (A), B)</code> or<br />
+<code>B = a * prod (A, trans (B))</code> or<br />
+<code>B = a * prod (trans (A), trans (B))</code> or<br />
+<code>B = a * prod (herm (A), B)</code> or<br />
+<code>B = a * prod (A, herm (B))</code> or<br />
+<code>B = a * prod (herm (A), trans (B))</code> or<br />
+<code>B = a * prod (trans (A), herm (B))</code> or<br />
+<code>B = a * prod (herm (A), herm (B))</code></td>
+<td><em>B &lt;- a op (A) op (B)</em> with<br />
+&nbsp; <em>op (X) = X</em> or<br />
+&nbsp; <em>op (X) = X</em><sup><em>T</em></sup> or<br />
+&nbsp; <em>op (X) = X</em><sup><em>H</em></sup></td>
+<td>Computes the scaled product of two matrices.</td>
+</tr>
+<tr>
+<td><code>_t_sm</code></td>
+<td><code>C = solve (A, B, tag)</code> or<br />
+<code>inplace_solve (A, B, tag)</code> or<br />
+<code>C = solve (trans (A), B, tag)</code> or<code><br />
+inplace_solve (trans (A), B, tag)</code> or<code><br />
+C = solve (herm (A), B, tag)</code> or<code><br />
+inplace_solve (herm (A), B, tag)</code></td>
+<td><em>C &lt;- A</em><sup><em>-1</em></sup> <em>B</em>
+or<em><br />
+B &lt;- A</em><sup><em>-1</em></sup> <em>B</em> or<em><br />
+C &lt;-
+A</em><sup><em>T</em></sup><sup><sup><em>-1</em></sup></sup>
+<em>B</em> or<em><br />
+B &lt;- A</em><sup><em>-1</em></sup> <em>B</em> or<em><br />
+C &lt;-
+A</em><sup><em>H</em></sup><sup><sup><em>-1</em></sup></sup>
+<em>B</em> or<em><br />
+B &lt;-
+A</em><sup><em>H</em></sup><sup><sup><em>-1</em></sup></sup>
+<em>B</em></td>
+<td>Solves a system of linear equations with triangular form, i.e.
+<em>A</em> is triangular.</td>
+</tr>
+<tr>
+<td><code>_g_mm<br />
+_s_mm<br />
+_h_mm</code></td>
+<td><code>C = a * prod (A, B) + b * C</code> or<br />
+<code>C = a * prod (trans (A), B) + b * C</code> or<br />
+<code>C = a * prod (A, trans (B)) + b * C</code> or<br />
+<code>C = a * prod (trans (A), trans (B)) + b * C</code> or<br />
+<code>C = a * prod (herm (A), B) + b * C</code> or<br />
+<code>C = a * prod (A, herm (B)) + b * C</code> or<br />
+<code>C = a * prod (herm (A), trans (B)) + b * C</code> or<br />
+<code>C = a * prod (trans (A), herm (B)) + b * C</code> or<br />
+<code>C = a * prod (herm (A), herm (B)) + b * C</code></td>
+<td><em>C &lt;- a op (A) op (B) + b C</em> with<br />
+&nbsp; <em>op (X) = X</em> or<br />
+&nbsp; <em>op (X) = X</em><sup><em>T</em></sup> or<br />
+&nbsp; <em>op (X) = X</em><sup><em>H</em></sup></td>
+<td>Adds the scaled product of two matrices.</td>
+</tr>
+<tr>
+<td><code>_s_rk<br />
+_h_rk</code></td>
+<td><code>B = a * prod (A, trans (A)) + b * B</code> or<br />
+<code>B = a * prod (trans (A), A) + b * B</code> or<br />
+<code>B = a * prod (A, herm (A)) + b * B</code> or<br />
+<code>B = a * prod (herm (A), A) + b * B</code></td>
+<td><em>B &lt;- a A A</em><sup><em>T</em></sup> <em>+ b B</em>
+or<em><br />
+B &lt;- a A</em><sup><em>T</em></sup> <em>A + b B</em> or<br />
+<em>B &lt;- a A A</em><sup><em>H</em></sup> <em>+ b B</em>
+or<em><br />
+B &lt;- a A</em><sup><em>H</em></sup> <em>A + b B</em></td>
+<td>Performs a symmetric or hermitian rank <em>k</em> update.</td>
+</tr>
+<tr>
+<td><code>_s_r2k<br />
+_h_r2k</code></td>
+<td><code>C = a * prod (A, trans (B)) +<br />
+&nbsp;a * prod (B, trans (A)) + b * C</code> or<br />
+<code>C = a * prod (trans (A), B) +<br />
+&nbsp;a * prod (trans (B), A) + b * C</code> or<br />
+<code>C = a * prod (A, herm (B)) +<br />
+&nbsp;conj (a) * prod (B, herm (A)) + b * C</code> or<br />
+<code>C = a * prod (herm (A), B) +<br />
+&nbsp;conj (a) * prod (herm (B), A) + b * C</code></td>
+<td><em>C &lt;- a A B</em><sup><em>T</em></sup> <em>+ a B
+A</em><sup><em>T</em></sup> <em>+ b C</em> or<em><br />
+C &lt;- a A</em><sup><em>T</em></sup> <em>B + a
+B</em><sup><em>T</em></sup> <em>A + b C</em> or<em><br />
+C &lt;- a A B</em><sup><em>H</em></sup> <em>+
+a</em><sup><em>-</em></sup> <em>B A</em><sup><em>H</em></sup> <em>+
+b C</em> or<em><br />
+C &lt;- a A</em><sup><em>H</em></sup> <em>B +
+a</em><sup><em>-</em></sup> <em>B</em><sup><em>H</em></sup> <em>A +
+b C</em></td>
+<td>Performs a symmetric or hermitian rank <em>2 k</em>
+update.</td>
+</tr>
+</tbody>
+</table>
+
+<h2>Storage Layout</h2>
+
+<p>uBLAS supports many different storage layouts. The full details can be
+found at the <a href="types_overview.html">Overview of Types</a>. Most types like 
+<code>vector&lt;double&gt;</code> and <code>matrix&lt;double&gt;</code> are 
+by default compatible to C arrays, but can also be configured to contain
+FORTAN compatible data.
+</p>
+
+<h2>Compatibility</h2>
+<p>For compatibility reasons we provide array like indexing for vectors and matrices. For some types (hermitian, sparse etc) this can be expensive for matrices due to the needed temporary proxy objects.</p>
+<p>uBLAS uses STL compatible allocators for the allocation of the storage required for it's containers.</p>
+<h2>Benchmark Results</h2>
+<p>The following tables contain results of one of our benchmarks.
+This benchmark compares a native C implementation ('C array') and
+some library based implementations. The safe variants based on the
+library assume aliasing, the fast variants do not use temporaries
+and are functionally equivalent to the native C implementation.
+Besides the generic vector and matrix classes the benchmark
+utilizes special classes <code>c_vector</code> and
+<code>c_matrix</code>, which are intended to avoid every overhead
+through genericity.</p>
+<p>The benchmark program <strong>bench1</strong> was compiled with GCC 4.0 and run on an Athlon 64 3000+. Times are scales for reasonable precision by running <strong>bench1 100</strong>.</p>
+<p>First we comment the results for double vectors and matrices of dimension 3 and 3 x 3, respectively.</p>
+<table border="1" summary="1st benchmark">
+<tbody>
+<tr>
+<th align="left">Comment</th>
+</tr>
+<tr>
+<td rowspan="3">inner_prod</td>
+<td>C array</td>
+<td align="right">0.61</td>
+<td align="right">782</td>
+<td rowspan="3">Some abstraction penalty</td>
+</tr>
+<tr>
+<td>c_vector</td>
+<td align="right">0.86</td>
+<td align="right">554</td>
+</tr>
+<tr>
+<td>vector&lt;unbounded_array&gt;</td>
+<td align="right">1.02</td>
+<td align="right">467</td>
+</tr>
+<tr>
+<td rowspan="5">vector + vector</td>
+<td>C array</td>
+<td align="right">0.51</td>
+<td align="right">1122</td>
+<td rowspan="5">Abstraction penalty: factor 2</td>
+</tr>
+<tr>
+<td>c_vector fast</td>
+<td align="right">1.17</td>
+<td align="right">489</td>
+</tr>
+<tr>
+<td>vector&lt;unbounded_array&gt; fast</td>
+<td align="right">1.32</td>
+<td align="right">433</td>
+</tr>
+<tr>
+<td>c_vector safe</td>
+<td align="right">2.02</td>
+<td align="right">283</td>
+</tr>
+<tr>
+<td>vector&lt;unbounded_array&gt; safe</td>
+<td align="right">6.95</td>
+<td align="right">82</td>
+</tr>
+<tr>
+<td rowspan="5">outer_prod</td>
+<td>C array</td>
+<td align="right">0.59</td>
+<td align="right">872</td>
+<td rowspan="5">Some abstraction penalty</td>
+</tr>
+<tr>
+<td>c_matrix, c_vector fast</td>
+<td align="right">0.88</td>
+<td align="right">585</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt;, vector&lt;unbounded_array&gt; fast</td>
+<td align="right">0.90</td>
+<td align="right">572</td>
+</tr>
+<tr>
+<td>c_matrix, c_vector safe</td>
+<td align="right">1.66</td>
+<td align="right">310</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt;, vector&lt;unbounded_array&gt; safe</td>
+<td align="right">2.95</td>
+<td align="right">175</td>
+</tr>
+<tr>
+<td rowspan="5">prod (matrix, vector)</td>
+<td>C array</td>
+<td align="right">0.64</td>
+<td align="right">671</td>
+<td rowspan="5">No significant abstraction penalty</td>
+</tr>
+<tr>
+<td>c_matrix, c_vector fast</td>
+<td align="right">0.70</td>
+<td align="right">613</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt;, vector&lt;unbounded_array&gt; fast</td>
+<td align="right">0.79</td>
+<td align="right">543</td>
+</tr>
+<tr>
+<td>c_matrix, c_vector safe</td>
+<td align="right">0.95</td>
+<td align="right">452</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt;, vector&lt;unbounded_array&gt; safe</td>
+<td align="right">2.61</td>
+<td align="right">164</td>
+</tr>
+<tr>
+<td rowspan="5">matrix + matrix</td>
+<td>C array</td>
+<td align="right">0.75</td>
+<td align="right">686</td>
+<td rowspan="5">No significant abstraction penalty</td>
+</tr>
+<tr>
+<td>c_matrix fast</td>
+<td align="right">0.99</td>
+<td align="right">520</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt; fast</td>
+<td align="right">1.29</td>
+<td align="right">399</td>
+</tr>
+<tr>
+<td>c_matrix safe</td>
+<td align="right">1.7</td>
+<td align="right">303</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt; safe</td>
+<td align="right">3.14</td>
+<td align="right">164</td>
+</tr>
+<tr>
+<td rowspan="5">prod (matrix, matrix)</td>
+<td>C array</td>
+<td align="right">0.94</td>
+<td align="right">457</td>
+<td rowspan="5">No significant abstraction penalty</td>
+</tr>
+<tr>
+<td>c_matrix fast</td>
+<td align="right">1.17</td>
+<td align="right">367</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt; fast</td>
+<td align="right">1.34</td>
+<td align="right">320</td>
+</tr>
+<tr>
+<td>c_matrix safe</td>
+<td align="right">1.56</td>
+<td align="right">275</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt; safe</td>
+<td align="right">2.06</td>
+<td align="right">208</td>
+</tr>
+</tbody>
+</table>
+<p>We notice a two fold performance loss for small vectors and matrices: first the general abstraction penalty for using classes, and then a small loss when using the generic vector and matrix classes. The difference w.r.t. alias assumptions is also significant.</p>
+<p>Next we comment the results for double vectors and matrices of
+dimension 100 and 100 x 100, respectively.</p>
+<table border="1" summary="2nd benchmark">
+<tbody>
+<tr>
+<th align="left">Operation</th>
+<th align="left">Implementation</th>
+<th align="left">Elapsed [s]</th>
+<th align="left">MFLOP/s</th>
+<th align="left">Comment</th>
+</tr>
+<tr>
+<td rowspan="3">inner_prod</td>
+<td>C array</td>
+<td align="right">0.64</td>
+<td align="right">889</td>
+<td rowspan="3">No significant abstraction penalty</td>
+</tr>
+<tr>
+<td>c_vector</td>
+<td align="right">0.66</td>
+<td align="right">862</td>
+</tr>
+<tr>
+<td>vector&lt;unbounded_array&gt;</td>
+<td align="right">0.66</td>
+<td align="right">862</td>
+</tr>
+<tr>
+<td rowspan="5">vector + vector</td>
+<td>C array</td>
+<td align="right">0.64</td>
+<td align="right">894</td>
+<td rowspan="5">No significant abstraction penalty</td>
+</tr>
+<tr>
+<td>c_vector fast</td>
+<td align="right">0.66</td>
+<td align="right">867</td>
+</tr>
+<tr>
+<td>vector&lt;unbounded_array&gt; fast</td>
+<td align="right">0.66</td>
+<td align="right">867</td>
+</tr>
+<tr>
+<td>c_vector safe</td>
+<td align="right">1.14</td>
+<td align="right">501</td>
+</tr>
+<tr>
+<td>vector&lt;unbounded_array&gt; safe</td>
+<td align="right">1.23</td>
+<td align="right">465</td>
+</tr>
+<tr>
+<td rowspan="5">outer_prod</td>
+<td>C array</td>
+<td align="right">0.50</td>
+<td align="right">1144</td>
+<td rowspan="5">No significant abstraction penalty</td>
+</tr>
+<tr>
+<td>c_matrix, c_vector fast</td>
+<td align="right">0.71</td>
+<td align="right">806</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt;, vector&lt;unbounded_array&gt; fast</td>
+<td align="right">0.57</td>
+<td align="right">1004</td>
+</tr>
+<tr>
+<td>c_matrix, c_vector safe</td>
+<td align="right">1.91</td>
+<td align="right">300</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt;, vector&lt;unbounded_array&gt; safe</td>
+<td align="right">0.89</td>
+<td align="right">643</td>
+</tr>
+<tr>
+<td rowspan="5">prod (matrix, vector)</td>
+<td>C array</td>
+<td align="right">0.65</td>
+<td align="right">876</td>
+<td rowspan="5">No significant abstraction penalty</td>
+</tr>
+<tr>
+<td>c_matrix, c_vector fast</td>
+<td align="right">0.65</td>
+<td align="right">876</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt;, vector&lt;unbounded_array&gt;
+fast</td>
+<td align="right">0.66</td>
+<td align="right">863</td>
+</tr>
+<tr>
+<td>c_matrix, c_vector safe</td>
+<td align="right">0.66</td>
+<td align="right">863</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt;, vector&lt;unbounded_array&gt;
+safe</td>
+<td align="right">0.66</td>
+<td align="right">863</td>
+</tr>
+<tr>
+<td rowspan="5">matrix + matrix</td>
+<td>C array</td>
+<td align="right">0.96</td>
+<td align="right">596</td>
+<td rowspan="5">No significant abstraction penalty</td>
+</tr>
+<tr>
+<td>c_matrix fast</td>
+<td align="right">1.21</td>
+<td align="right">473</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt; fast</td>
+<td align="right">1.00</td>
+<td align="right">572</td>
+</tr>
+<tr>
+<td>c_matrix safe</td>
+<td align="right">2.44</td>
+<td align="right">235</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt; safe</td>
+<td align="right">1.30</td>
+<td align="right">440</td>
+</tr>
+<tr>
+<td rowspan="5">prod (matrix, matrix)</td>
+<td>C array</td>
+<td align="right">0.70</td>
+<td align="right">813</td>
+<td rowspan="5">No significant abstraction penalty</td>
+</tr>
+<tr>
+<td>c_matrix fast</td>
+<td align="right">0.73</td>
+<td align="right">780</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt; fast</td>
+<td align="right">0.76</td>
+<td align="right">749</td>
+</tr>
+<tr>
+<td>c_matrix safe</td>
+<td align="right">0.75</td>
+<td align="right">759</td>
+</tr>
+<tr>
+<td>matrix&lt;unbounded_array&gt; safe</td>
+<td align="right">0.76</td>
+<td align="right">749</td>
+</tr>
+</tbody>
+</table>
+<p>For larger vectors and matrices the general abstraction penalty
+for using classes seems to decrease, the small loss when using
+generic vector and matrix classes seems to remain. The difference
+w.r.t. alias assumptions remains visible, too.</p>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/products.html b/doc/products.html
new file mode 100644
index 0000000..563a4b8
--- /dev/null
+++ b/doc/products.html
@@ -0,0 +1,318 @@
+?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>Special Products</title>
+  <meta name="GENERATOR" content="Quanta Plus" />
+  <meta name="AUTHOR" content="Gunter Winkler" />
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+  <link rel="stylesheet" href="ublas.css" type="text/css" />
+  <script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+  <script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+</head>
+<body>
+
+<h1><img src="../../../../boost.png" align="middle" />Special Products </h1>
+<div class="toc" id="toc"></div>
+
+<h2>Functions</h2>
+
+<table summary="" border=0 cellpadding=0 cellspacing=0>
+<tr>
+<td class="memItemLeft" nowrap align=right valign=top>template&lt;class V, class E1, class E2&gt; BOOST_UBLAS_INLINE V &amp;&nbsp;</td>
+<td class="memItemRight" valign=bottom><a class="el" href="#ga8">axpy_prod</a> (const matrix_expression&lt; E1 &gt; &amp;e1, const vector_expression&lt; E2 &gt; &amp;e2, V &amp;v, bool init=true)</td></tr>
+
+<tr>
+<td class="mdescLeft">&nbsp;</td>
+<td class="mdescRight">computes <code>v += A x</code> or <code>v = A x</code> in an optimized fashion.  <a href="#ga8"></a><br /><br /></td></tr>
+<tr>
+<td class="memItemLeft" nowrap align=right valign=top>template&lt;class V, class E1, class E2&gt; BOOST_UBLAS_INLINE V &amp;&nbsp;</td>
+<td class="memItemRight" valign=bottom><a class="el" href="#ga9">axpy_prod</a> (const vector_expression&lt; E1 &gt; &amp;e1, const matrix_expression&lt; E2 &gt; &amp;e2, V &amp;v, bool init=true)</td></tr>
+
+<tr>
+<td class="mdescLeft">&nbsp;</td>
+<td class="mdescRight">computes <code>v += A<sup>T</sup> x</code> or <code>v = A<sup>T</sup> x</code> in an optimized fashion.  <a href="#ga9"></a><br /><br /></td></tr>
+<tr>
+<td class="memItemLeft" nowrap align=right valign=top>template&lt;class M, class E1, class E2&gt; BOOST_UBLAS_INLINE M &amp;&nbsp;</td>
+<td class="memItemRight" valign=bottom><a class="el" href="#ga7">axpy_prod</a> (const matrix_expression&lt; E1 &gt; &amp;e1, const matrix_expression&lt; E2 &gt; &amp;e2, M &amp;m, bool init=true)</td></tr>
+
+<tr>
+<td class="mdescLeft">&nbsp;</td>
+<td class="mdescRight">computes <code>M += A X</code> or <code>M = A X</code> in an optimized fashion.  <a href="#ga7"></a><br /><br /></td></tr>
+<tr>
+<td class="memItemLeft" nowrap align=right valign=top>template&lt;class M, class E1, class E2&gt; BOOST_UBLAS_INLINE M &amp;&nbsp;</td>
+<td class="memItemRight" valign=bottom><a class="el" href="#ga6">opb_prod</a> (const matrix_expression&lt; E1 &gt; &amp;e1, const matrix_expression&lt; E2 &gt; &amp;e2, M &amp;m, bool init=true)</td></tr>
+
+<tr>
+<td class="mdescLeft">&nbsp;</td>
+<td class="mdescRight">computes <code>M += A X</code> or <code>M = A X</code> in an optimized fashion.  <a href="#ga6"></a><br /><br /></td></tr>
+</table>
+
+<hr />
+
+<a class="anchor" name="ga8" doxytag="boost::numeric::ublas::axpy_prod" ></a>
+<table summary="" class="mdTable" width="95%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> BOOST_UBLAS_INLINE V&amp; axpy_prod           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">const matrix_expression&lt; E1 &gt; &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>e1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const vector_expression&lt; E2 &gt; &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>e2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>V &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>v</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>bool&nbsp;</td>
+          <td class="mdname" nowrap> <em>init</em> = <code>true</code></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+
+<p>
+computes <code>v += A x</code> or <code>v = A x</code> in an optimized fashion. 
+</p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+  <table summary="" border="0" cellspacing="2" cellpadding="0">
+    <tr><td></td><td valign=top><em>e1</em>&nbsp;</td><td>the matrix expression <code>A</code> </td></tr>
+    <tr><td></td><td valign=top><em>e2</em>&nbsp;</td><td>the vector expression <code>x</code> </td></tr>
+    <tr><td></td><td valign=top><em>v</em>&nbsp;</td><td>the result vector <code>v</code> </td></tr>
+    <tr><td></td><td valign=top><em>init</em>&nbsp;</td><td>a boolean parameter</td></tr>
+  </table>
+</dl>
+<code>axpy_prod(A, x, v, init)</code> implements the well known axpy-product. Setting <em>init</em> to <code>true</code> is equivalent to call <code>v.clear()</code> before <code>axpy_prod</code>. Currently <em>init</em> defaults to <code>true</code>, but this may change in the future.<p>
+Up to now there are some specialisation for compressed matrices that give a large speed up compared to prod.    </td>
+  </tr>
+</table>
+
+
+<a class="anchor" name="ga9" doxytag="boost::numeric::ublas::axpy_prod" ></a>
+<table summary="" class="mdTable" width="95%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> BOOST_UBLAS_INLINE V&amp; axpy_prod           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">const vector_expression&lt; E1 &gt; &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>e1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const matrix_expression&lt; E2 &gt; &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>e2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>V &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>v</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>bool&nbsp;</td>
+          <td class="mdname" nowrap> <em>init</em> = <code>true</code></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+
+<p>
+computes <code>v += A<sup>T</sup> x</code> or <code>v = A<sup>T</sup> x</code> in an optimized fashion. 
+</p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+  <table summary="" border="0" cellspacing="2" cellpadding="0">
+    <tr><td></td><td valign=top><em>e1</em>&nbsp;</td><td>the vector expression <code>x</code> </td></tr>
+    <tr><td></td><td valign=top><em>e2</em>&nbsp;</td><td>the matrix expression <code>A</code> </td></tr>
+    <tr><td></td><td valign=top><em>v</em>&nbsp;</td><td>the result vector <code>v</code> </td></tr>
+    <tr><td></td><td valign=top><em>init</em>&nbsp;</td><td>a boolean parameter</td></tr>
+  </table>
+</dl>
+<code>axpy_prod(x, A, v, init)</code> implements the well known axpy-product. Setting <em>init</em> to <code>true</code> is equivalent to call <code>v.clear()</code> before <code>axpy_prod</code>. Currently <em>init</em> defaults to <code>true</code>, but this may change in the future.<p>
+Up to now there are some specialisation for compressed matrices that give a large speed up compared to prod.    </td>
+  </tr>
+</table>
+
+<a class="anchor" name="ga7" doxytag="boost::numeric::ublas::axpy_prod" ></a>
+<table summary="" class="mdTable" width="95%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> BOOST_UBLAS_INLINE M&amp; axpy_prod           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">const matrix_expression&lt; E1 &gt; &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>e1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const matrix_expression&lt; E2 &gt; &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>e2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>M &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>bool&nbsp;</td>
+          <td class="mdname" nowrap> <em>init</em> = <code>true</code></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+
+<p>
+computes <code>M += A X</code> or <code>M = A X</code> in an optimized fashion. 
+</p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+  <table summary="" border="0" cellspacing="2" cellpadding="0">
+    <tr><td></td><td valign=top><em>e1</em>&nbsp;</td><td>the matrix expression <code>A</code> </td></tr>
+    <tr><td></td><td valign=top><em>e2</em>&nbsp;</td><td>the matrix expression <code>X</code> </td></tr>
+    <tr><td></td><td valign=top><em>m</em>&nbsp;</td><td>the result matrix <code>M</code> </td></tr>
+    <tr><td></td><td valign=top><em>init</em>&nbsp;</td><td>a boolean parameter</td></tr>
+  </table>
+</dl>
+<code>axpy_prod(A, X, M, init)</code> implements the well known axpy-product. Setting <em>init</em> to <code>true</code> is equivalent to call <code>M.clear()</code> before <code>axpy_prod</code>. Currently <em>init</em> defaults to <code>true</code>, but this may change in the future.<p>
+Up to now there are no specialisations.    </td>
+  </tr>
+</table>
+
+<a class="anchor" name="ga6" doxytag="boost::numeric::ublas::opb_prod" ></a>
+
+<table summary="" class="mdTable" width="95%" cellpadding="2" cellspacing="0">
+  <tr>
+    <td class="mdRow">
+      <table summary="" cellpadding="0" cellspacing="0" border="0">
+        <tr>
+          <td class="md" nowrap valign="top"> BOOST_UBLAS_INLINE M&amp; opb_prod           </td>
+          <td class="md" valign="top">(&nbsp;</td>
+          <td class="md" nowrap valign="top">const matrix_expression&lt; E1 &gt; &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>e1</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>const matrix_expression&lt; E2 &gt; &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>e2</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>M &amp;&nbsp;</td>
+          <td class="mdname" nowrap> <em>m</em>, </td>
+        </tr>
+        <tr>
+          <td class="md" nowrap align="right"></td>
+          <td></td>
+          <td class="md" nowrap>bool&nbsp;</td>
+          <td class="mdname" nowrap> <em>init</em> = <code>true</code></td>
+        </tr>
+        <tr>
+          <td></td>
+          <td class="md">)&nbsp;</td>
+          <td class="md" colspan="2"></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table summary="" cellspacing=5 cellpadding=0 border=0>
+  <tr>
+    <td>
+      &nbsp;
+    </td>
+    <td>
+
+<p>
+computes <code>M += A X</code> or <code>M = A X</code> in an optimized fashion. 
+</p>
+<dl compact><dt><b>Parameters:</b></dt><dd>
+  <table summary="" border="0" cellspacing="2" cellpadding="0">
+    <tr><td></td><td valign=top><em>e1</em>&nbsp;</td><td>the matrix expression <code>A</code> </td></tr>
+    <tr><td></td><td valign=top><em>e2</em>&nbsp;</td><td>the matrix expression <code>X</code> </td></tr>
+    <tr><td></td><td valign=top><em>m</em>&nbsp;</td><td>the result matrix <code>M</code> </td></tr>
+    <tr><td></td><td valign=top><em>init</em>&nbsp;</td><td>a boolean parameter</td></tr>
+  </table>
+</dl>
+<code>opb_prod(A, X, M, init)</code> implements the well known axpy-product. Setting <em>init</em> to <code>true</code> is equivalent to call <code>M.clear()</code> before <code>opb_prod</code>. Currently <em>init</em> defaults to <code>true</code>, but this may change in the future.<p>
+This function may give a speedup if <code>A</code> has less columns than rows, because the product is computed as a sum of outer products.    </td>
+  </tr>
+</table>
+
+
+
+<hr />
+<p>Copyright (&copy;) 2000-2004 Michael Stevens, Mathias Koch, 
+Joerg Walter, Gunter Winkler<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/range.html b/doc/range.html
new file mode 100644
index 0000000..37213be
--- /dev/null
+++ b/doc/range.html
@@ -0,0 +1,229 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Range and slice</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Range and Slice Storage</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="range"></a>Range&lt;SizeType,DistanceType&gt;</h2>
+<h4>Description</h4>
+<p>The class <code>range</code> specifies a range of indicies. The range is a sequence of indices
+from a start value to stop value. The indices increase by one and exlude the stop value.
+<code>range</code> can therefore be used to specify ranges of elements from vectors and matrices.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/storage.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    range r (0, 3);
+    for (unsigned i = 0; i &lt; r.size (); ++ i) {
+        std::cout &lt;&lt; r (i) &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header storage.hpp.</p>
+<h4>Model of</h4>
+<p>Reversible Container.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of Reversible
+Container.</p>
+<h4>Public base classes</h4>
+<p>None.</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>range (size_type start, size_type stop)</code></td>
+<td>Constructs a range of indicies from <code>start</code> to <code>stop (excluded)</code>
+.</td>
+</tr>
+<tr>
+<td><code>size_type start () const</code></td>
+<td>Returns the beginning of the <code>range</code>.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the <code>range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i)
+const</code></td>
+<td>Returns the value <code>start + i</code> of the <code>i</code>
+-th element.</td>
+</tr>
+<tr>
+<td><code>range compose (const range &amp;r) const</code></td>
+<td>Returns the composite range from <code>start + r.start
+()</code> to <code>start + r.start () + r.size ()</code>.</td>
+</tr>
+<tr>
+<td><code>bool operator == (const range &amp;r) const</code></td>
+<td>Tests two ranges for equality.</td>
+</tr>
+<tr>
+<td><code>bool operator != (const range &amp;r) const</code></td>
+<td>Tests two ranges for inequality.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>range</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>range</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Preconditions</h4>
+<ul>
+<li><code>start () &lt;= stop ()</code></li>
+</ul>
+
+<h2><a name="slice"></a>Slice&lt;SizeType,DistanceType&gt;</h2>
+<h4>Description</h4>
+<p>The class <code>slice</code> specifies a 'slice' of indicies. Slices are more general
+then ranges, the stride allows the sequence of indicies to increase and decrease by the specified amount between element.
+<code>slice</code> can therefore be used to specify slices of element from vectors and matrices.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/storage.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    slice s (0, 1, 3);
+    for (unsigned i = 0; i &lt; s.size (); ++ i) {
+        std::cout &lt;&lt; s (i) &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header storage.hpp.</p>
+<h4>Model of</h4>
+<p>Reversible Container.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of Reversible
+Container.</p>
+<h4>Public base classes</h4>
+<p>None.</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>slice (size_type start, size_type stride, size_type
+size)</code></td>
+<td>Constructs a slice <code>start,start+stride,start+2*stride...</code> with 
+<code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>size_type start () const</code></td>
+<td>Returns the beginning of the <code>slice</code>.</td>
+</tr>
+<tr>
+<td><code>size_type stride () const</code></td>
+<td>Returns the stride of the <code>slice</code>.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the <code>slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i)
+const</code></td>
+<td>Returns the value <code>start + i * stride</code> of the
+<code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>slice compose (const range &amp;r) const</code></td>
+<td>Returns the composite slice from <code>start + stride * r.start
+()</code> to <code>start + stride * (r.start () + r.size ())</code>
+with stride <code>stride</code>.</td>
+</tr>
+<tr>
+<td><code>slice compose (const slice &amp;s) const</code></td>
+<td>Returns the composite slice from <code>start + stride * s.start
+()</code> to <code>start + stride * s.stride () * (s.start () +
+s.size ())</code> with stride <code>stride * s.stride ()</code>
+.</td>
+</tr>
+<tr>
+<td><code>bool operator == (const slice &amp;s) const</code></td>
+<td>Tests two slices for equality.</td>
+</tr>
+<tr>
+<td><code>bool operator != (const slice &amp;s) const</code></td>
+<td>Tests two slices for inequality.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>slice</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Preconditions</h4>
+<ul>
+<li>None all strides are vaild. However when an index is returned or an iterator is dereferenced its
+value must be representable as the size_type.</li>
+</ul>
+   <hr/>
+   <p>
+      Copyright (&copy;) 2000-2004 Michael Stevens, Mathias Koch,
+      Joerg Walter, Gunter Winkler<br />
+      Use, modification and distribution are subject to the
+      Boost Software License, Version 1.0.
+      (See accompanying file LICENSE_1_0.txt
+      or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+         http://www.boost.org/LICENSE_1_0.txt
+      </a>).
+   </p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/release_notes.html b/doc/release_notes.html
new file mode 100644
index 0000000..2a10e07
--- /dev/null
+++ b/doc/release_notes.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content="HTML Tidy for Linux (vers 6 November 2007), see www.w3.org" />
+<!-- tidy options: -w 120 -asxhtml -clean - - vertical-space yes -f index.html.err -m index.html -->
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Boost Basic Linear Algebra - Release Notes</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" alt="logo"/>Boost Basic Linear Algebra - Release Notes</h1>
+
+<div class="navigation">
+<a href="index.html">back to uBLAS home</a>
+</div>
+<div class="toc" id="toc"></div>
+
+<h2>Release 1.52.0</h2>
+
+<h3>improvements</h3>
+
+<ul>
+<li><a href="https://svn.boost.org/trac/boost/ticket/4024">[4024]</a> improve performance of inplace_solve</li>
+<li><a href="https://svn.boost.org/trac/boost/ticket/6511">[6511]</a> Division by scalar should use enable_if&lt;&gt;</li>
+<li><a href="https://svn.boost.org/trac/boost/ticket/7297">[7297]</a> Make the free functions 'num_columns' and 'num_rows' support the uBLAS traits system and better work with expression types</li>
+</ul>
+
+<h3>bug fixes</h3>
+
+<ul>
+<li><a href="https://svn.boost.org/trac/boost/ticket/7296">[7296]</a> fixes and improvements to test utility functions</li>
+<li><a href="https://svn.boost.org/trac/boost/ticket/7363">[7363]</a> fixed coordinate_matrix::sort() for gcc 4.7 and others</li>
+</ul>
+
+<h2>Release 1.43.0</h2>
+
+<h3>bug fixes</h3>
+
+<ul>
+<li><a href="https://svn.boost.org/trac/boost/ticket/3968">[3968]</a> fixed coordinate_matrix sort problem on MSVC10
+</li>
+<li><a href="https://svn.boost.org/trac/boost/ticket/3539">[3539]</a>
+	changed computation of <code>norm_inf</code> for complex types to match
+	mathematical definition. <br />
+	<b>Note:</b> This might cause a performance drop
+	because now <code>std::abs(z)</code> is called for each vector element.
+	The old implementation used <code>std::max(std::abs(real(z)),std::abs(imag(z))</code>.
+	Further <code>norm_inf</code> and <code>norm_1</code> will now return
+	the same values for complex vector.
+</li>
+<li><a href="https://svn.boost.org/trac/boost/ticket/3501">[3501]</a> Moved free functions in <code>concepts.hpp</code> into anonymous namespace.
+</li>
+</ul>
+
+<h2>Release 1.41.1</h2>
+
+<h3>new features</h3>
+
+<ul>
+<li>Move semantics of vector/matrix container assignments have been
+implemented. They can be enabled by setting
+BOOST_UBLAS_MOVE_SEMANTICS. More details are on the <a
+href="options.html">preprocessor options page</a>.
+</li>
+<li>Introduce new free functions. See <a href="https://svn.boost.org/trac/boost/ticket/3449" target="_blank">[3449]</a>, 
+the new tests in <tt>libs/numeric/ublas/test</tt> and the inline documentation of the files in <tt>boost/numeric/ublas/operation/</tt>.
+</li>
+</ul>
+
+<h3>bug fixes</h3>
+
+<ul>
+<li><a href="https://svn.boost.org/trac/boost/ticket/3293">[3293]</a> Fix resizing problem in <code>identity_matrix</code>
+</li>
+<li><a href="https://svn.boost.org/trac/boost/ticket/3499">[3499]</a> Add DefaultConstructible to concept checks
+</li>
+</ul>
+
+<h2>Release 1.40.0 and before</h2>
+<ul>
+<li>Release notes were not available in this form.</li>
+</ul>
+
+<hr />
+<p>Copyright (&copy;) 2000-2009 Joerg Walter, Mathias Koch, Gunter Winkler<br />
+   Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<!-- Created: Sun Sep 13 00:57:13 CEST 2009 -->
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+  </body>
+</html>
diff --git a/doc/samples/Jamfile.v2 b/doc/samples/Jamfile.v2
new file mode 100644
index 0000000..55a8e6a
--- /dev/null
+++ b/doc/samples/Jamfile.v2
@@ -0,0 +1,228 @@
+# Copyright Michael Stevens 2004
+
+# Use, modification, and distribution is subject to the Boost Software
+# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+# bring in rules for testing
+
+# Boost uBLAS library documentation samples
+
+# Project requirements
+project samples
+    : requirements
+      <toolset>borland:<cxxflags>"-w-8026 -w-8027 -w-8057 -w-8084 -w-8092"
+      <toolset>kylix:<cxxflags>"-w-8026 -w-8027 -w-8057 -w-8084 -w-8092"
+    ;
+
+exe unbounded_array
+    : unbounded_array.cpp
+    ;
+
+exe bounded_array
+    : bounded_array.cpp
+    ;
+
+exe range
+    : range.cpp
+    ;
+
+exe slice
+    : slice.cpp
+    ;
+
+exe map_array
+    : map_array.cpp
+    ;
+
+exe vector
+    : vector.cpp
+    ;
+
+exe unit_vector
+    : unit_vector.cpp
+    ;
+
+exe zero_vector
+    : zero_vector.cpp
+    ;
+
+exe mapped_vector
+    : mapped_vector.cpp
+    ;
+
+exe compressed_vector
+    : compressed_vector.cpp
+    ;
+
+exe coordinate_vector
+    : coordinate_vector.cpp
+    ;
+
+exe vector_range
+    : vector_range.cpp
+    ;
+
+exe vector_range_project
+    : vector_range_project.cpp
+    ;
+
+exe vector_slice
+    : vector_slice.cpp
+    ;
+
+exe vector_slice_project
+    : vector_slice_project.cpp
+    ;
+
+exe vector_unary
+    : vector_unary.cpp
+    ;
+
+exe vector_binary
+    : vector_binary.cpp
+    ;
+
+exe vector_binary_outer
+    : vector_binary_outer.cpp
+    ;
+
+exe vector_binary_scalar
+    : vector_binary_scalar.cpp
+    ;
+
+exe vector_unary_redux
+    : vector_unary_redux.cpp
+    ;
+
+exe vector_binary_redux
+    : vector_binary_redux.cpp
+    ;
+
+exe matrix
+    : matrix.cpp
+    ;
+
+exe identity_matrix
+    : identity_matrix.cpp
+    ;
+
+exe zero_matrix
+    : zero_matrix.cpp
+    ;
+
+exe mapped_matrix
+    : mapped_matrix.cpp
+    ;
+
+exe compressed_matrix
+    : compressed_matrix.cpp
+    ;
+
+exe coordinate_matrix
+    : coordinate_matrix.cpp
+    ;
+
+exe matrix_row
+    : matrix_row.cpp
+    ;
+
+exe matrix_row_project
+    : matrix_row_project.cpp
+    ;
+
+exe matrix_column
+    : matrix_column.cpp
+    ;
+
+exe matrix_column_project
+    : matrix_column_project.cpp
+    ;
+
+exe matrix_vector_range
+    : matrix_vector_range.cpp
+    ;
+
+exe matrix_vector_slice
+    : matrix_vector_slice.cpp
+    ;
+
+exe matrix_range
+    : matrix_range.cpp
+    ;
+
+exe matrix_range_project
+    : matrix_range_project.cpp
+    ;
+
+exe matrix_slice
+    : matrix_slice.cpp
+    ;
+
+exe matrix_slice_project
+    : matrix_slice_project.cpp
+    ;
+
+exe matrix_unary
+    : matrix_unary.cpp
+    ;
+
+exe matrix_binary
+    : matrix_binary.cpp
+    : <include>$(BOOST_ROOT)
+    ;
+
+exe matrix_binary_scalar
+    : matrix_binary_scalar.cpp
+    ;
+
+exe matrix_vector_binary
+    : matrix_vector_binary.cpp
+    ;
+
+exe matrix_vector_solve
+    : matrix_vector_solve.cpp
+    ;
+
+exe matrix_matrix_binary
+    : matrix_matrix_binary.cpp
+    ;
+
+exe matrix_matrix_solve
+    : matrix_matrix_solve.cpp
+    ;
+
+exe banded_matrix
+    : banded_matrix.cpp
+    ;
+
+exe banded_adaptor
+    : banded_adaptor.cpp
+    ;
+
+exe hermitian_matrix
+    : hermitian_matrix.cpp
+    ;
+
+exe hermitian_adaptor
+    : hermitian_adaptor.cpp
+    ;
+
+exe symmetric_matrix
+    : symmetric_matrix.cpp
+    ;
+
+exe symmetric_adaptor
+    : symmetric_adaptor.cpp
+    ;
+
+exe triangular_matrix
+    : triangular_matrix.cpp
+    ;
+
+exe triangular_adaptor
+    : triangular_adaptor.cpp
+    ;
+
+exe ex_triangular
+    : ex_triangular.cpp
+    ;
diff --git a/doc/samples/assignment_examples.cpp b/doc/samples/assignment_examples.cpp
new file mode 100644
index 0000000..bfad1f5
--- /dev/null
+++ b/doc/samples/assignment_examples.cpp
@@ -0,0 +1,319 @@
+//
+//  Copyright (c) 2010 Athanasios Iliopoulos
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/numeric/ublas/assignment.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+
+using namespace boost::numeric::ublas;
+
+int main() {
+        // Simple vector fill
+    vector<double> a(3);
+    a <<= 0, 1, 2;
+    std::cout << a << std::endl;
+    // [ 0 1 2]
+
+    // Vector from vector
+    vector<double> b(7);
+    b <<= a, 10, a;
+    std::cout << b << std::endl;
+    // [ 0 1 2 10 0 1 2]
+
+    // Simple matrix fill
+    matrix<double> A(3,3);
+    A <<= 0, 1, 2,
+         3, 4, 5,
+         6, 7, 8;
+    std::cout << A << std::endl;
+    // [ 0 1 2 ]
+    // [ 3 4 5 ]
+    // [ 6 7 8 ]
+
+    // Matrix from vector
+    A <<= 0, 1, 2,
+         3, 4, 5,
+         a;
+    std::cout << A << std::endl;
+    // [ 0 1 2 ]
+    // [ 3 4 5 ]
+    // [ 0 1 2 ]
+
+    // Matrix from vector - column assignment
+    A <<= move(0,2), traverse_policy::by_column(),
+         a;
+    std::cout << A << std::endl;
+    // [ 0 1 0 ]
+    // [ 3 4 1 ]
+    // [ 0 1 2 ]
+
+    // Another matrix from vector example (watch the wraping);
+    vector<double> c(9); c <<= 1, 2, 3, 4, 5, 6, 7, 8, 9;
+    A <<= c;
+    std::cout << A << std::endl;
+    // [ 1 2 3 ]
+    // [ 4 5 6 ]
+    // [ 7 8 9 ]
+
+    // If for performance(Benchmarks are not definite about that) or consistency reasons you need to disable wraping:
+    static next_row_manip endr; //This can be defined globally
+    A <<= traverse_policy::by_row_no_wrap(),
+            1, 2, 3, endr,
+            4, 5, 6, endr,
+            7, 8, 9, endr;
+    // [ 1 2 3 ]
+    // [ 4 5 6 ]
+    // [ 7 8 9 ]
+    // If by default you need to disable wraping define
+    // BOOST_UBLAS_DEFAULT_NO_WRAP_POLICY, in the compilation options,
+    // so that you avoid typing the "traverse_policy::by_row_no_wrap()".
+
+    //  Plus and minus assign:
+    A <<= fill_policy::index_plus_assign(),
+         3,2,1;
+    std::cout << A << std::endl;
+    // [ 4 4 4 ]
+    // [ 4 5 6 ]
+    // [ 7 8 9 ]
+
+    // Matrix from proxy
+    A <<= 0, 1, 2,
+         project(b, range(3,6)),
+         a;
+    std::cout << A << std::endl;
+    // [ 0 1 2 ]
+    // [10 0 1 ]
+    // [ 6 7 8 ]
+
+    // Matrix from matrix
+    matrix<double> B(6,6);
+    B <<= A, A,
+         A, A;
+    std::cout << B << std::endl;
+    // [ A A ]
+    // [ A A ]
+
+    // Matrix range (vector is similar)
+    B = zero_matrix<double>(6,6);
+    matrix_range<matrix<double> > mrB (B, range (1, 4), range (1, 4));
+    mrB <<= 1,2,3,4,5,6,7,8,9;
+    std::cout << B << std::endl;
+    // [ 0 0 0 0 0 0]
+    // [ 0 1 2 3 0 0]
+    // [ 0 4 5 6 0 0]
+    // [ 0 0 0 0 0 0]
+    // [ 0 0 0 0 0 0]
+    // [ 0 0 0 0 0 0]
+
+    // Horizontal concatenation can be achieved using this trick:
+    matrix<double> BH(3,9);
+    BH <<= A, A, A;
+    std::cout << BH << std::endl;
+    // [ A A A]
+
+    // Vertical concatenation can be achieved using this trick:
+    matrix<double> BV(9,3);
+    BV <<= A,
+          A,
+          A;
+    std::cout << BV << std::endl;
+    // [ A ]
+    // [ A ]
+    // [ A ]
+
+    // Watch the difference when assigning matrices for different traverse policies:
+    matrix<double> BR(9,9, 0);
+    BR <<= traverse_policy::by_row(), // This is the default, so this might as well be omitted.
+          A, A, A;
+    std::cout << BR << std::endl;
+    // [ A A A]
+    // [ 0 0 0]
+    // [ 0 0 0]
+
+    matrix<double> BC(9,9, 0);
+    BC <<= traverse_policy::by_column(),
+          A, A, A;
+    std::cout << BC << std::endl;
+    // [ A 0 0]
+    // [ A 0 0]
+    // [ A 0 0]
+
+    // The following will throw a run-time exception in debug mode (matrix mid-assignment wrap is not allowed) :
+    // matrix<double> C(7,7);
+    // C <<= A, A, A;
+
+    // Matrix from matrix with index manipulators
+    matrix<double> C(6,6,0);
+    C <<= A, move(3,0), A;
+    // [ A 0 ]
+    // [ 0 A ]
+
+    // A faster way for to construct this dense matrix.
+    matrix<double> D(6,6);
+    D <<= A, zero_matrix<double>(3,3),
+         zero_matrix<double>(3,3), A;
+    // [ A 0 ]
+    // [ 0 A ]
+
+    // The next_row and next_column index manipulators:
+    // note: next_row and next_column functions return
+    // a next_row_manip and and next_column_manip object.
+    // This is the manipulator we used earlier when we disabled
+    // wrapping.
+    matrix<double> E(2,4,0);
+    E <<= 1, 2, next_row(),
+         3, 4, next_column(),5;
+    std::cout << E << std::endl;
+    // [ 1 2 0 5 ]
+    // [ 3 4 0 0 ]
+
+    // The begin1 (moves to the begining of the column) index manipulator, begin2 does the same for the row:
+    matrix<double> F(2,4,0);
+    F <<= 1, 2, next_row(),
+         3, 4, begin1(),5;
+    std::cout << F << std::endl;
+    // [ 1 2 5 0 ]
+    // [ 3 4 0 0 ]
+
+    // The move (relative) and move_to(absolute) index manipulators (probably the most useful manipulators):
+    matrix<double> G(2,4,0);
+    G <<= 1, 2, move(0,1), 3,
+         move_to(1,3), 4;
+    std::cout << G << std::endl;
+    // [ 1 2 0 3 ]
+    // [ 0 0 0 4 ]
+
+    // Static equivallents (faster) when sizes are known at compile time:
+    matrix<double> Gs(2,4,0);
+    Gs <<= 1, 2, move<0,1>(), 3,
+         move_to<1,3>(), 4;
+    std::cout << Gs << std::endl;
+    // [ 1 2 0 3 ]
+    // [ 0 0 0 4 ]
+
+    // Choice of traverse policy (default is "row by row" traverse):
+
+    matrix<double> H(2,4,0);
+    H <<= 1, 2, 3, 4,
+         5, 6, 7, 8;
+    std::cout << H << std::endl;
+    // [ 1 2 3 4 ]
+    // [ 5 6 7 8 ]
+
+    H <<= traverse_policy::by_column(),
+        1, 2, 3, 4,
+        5, 6, 7, 8;
+    std::cout << H << std::endl;
+    // [ 1 3 5 7 ]
+    // [ 2 4 6 8 ]
+
+    // traverse policy can be changed mid assignment if desired.
+     matrix<double> H1(4,4,0);
+     H1 <<= 1, 2, 3, traverse_policy::by_column(), 1, 2, 3;
+
+    std::cout << H << std::endl;
+    // [1 2 3 1]
+    // [0 0 0 2]
+    // [0 0 0 3]
+    // [0 0 0 0]
+
+    // note: fill_policy and traverse_policy are namespaces, so you can use them
+    // by a using statement.
+
+    // For compressed and coordinate matrix types a push_back or insert fill policy can be chosen for faster assginment:
+    compressed_matrix<double> I(2, 2);
+    I <<=    fill_policy::sparse_push_back(),
+            0, 1, 2, 3;
+    std::cout << I << std::endl;
+    // [ 0 1 ]
+    // [ 2 3 ]
+
+    coordinate_matrix<double> J(2,2);
+    J<<=fill_policy::sparse_insert(),
+        1, 2, 3, 4;
+    std::cout << J << std::endl;
+    // [ 1 2 ]
+    // [ 3 4 ]
+
+    // A sparse matrix from another matrix works as with other types.
+    coordinate_matrix<double> K(3,3);
+    K<<=fill_policy::sparse_insert(),
+        J;
+    std::cout << K << std::endl;
+    // [ 1 2 0 ]
+    // [ 3 4 0 ]
+    // [ 0 0 0 ]
+
+    // Be careful this will not work:
+    //compressed_matrix<double> J2(4,4);
+    //J2<<=fill_policy::sparse_push_back(),
+     //   J,J;
+    // That's because the second J2's elements
+    // are attempted to be assigned at positions
+    // that come before the elements already pushed.
+    // Unfortunatelly that's the only thing you can do in this case
+    // (or of course make a custom agorithm):
+    compressed_matrix<double> J2(4,4);
+    J2<<=fill_policy::sparse_push_back(),
+        J, fill_policy::sparse_insert(),
+        J;
+
+    std::cout << J2 << std::endl;
+    // [  J   J  ]
+    // [ 0 0 0 0 ]
+    // [ 0 0 0 0 ]
+
+    // A different traverse policy doesn't change the result, only they order it is been assigned.
+    coordinate_matrix<double> L(3,3);
+    L<<=fill_policy::sparse_insert(), traverse_policy::by_column(),
+        J;
+    std::cout << L << std::endl;
+    // (same as previous)
+    // [ 1 2 0 ]
+    // [ 3 4 0 ]
+    // [ 0 0 0 ]
+
+    typedef coordinate_matrix<double>::size_type cmst;
+    const cmst size = 30;
+    //typedef fill_policy::sparse_push_back spb;
+    // Although the above could have been used the following is may be faster if
+    //  you use the policy often and for relatively small containers.
+    static fill_policy::sparse_push_back spb;
+
+    // A block diagonal sparse using a loop:
+    compressed_matrix<double> M(size, size, 4*15);
+    for (cmst i=0; i!=size; i+=J.size1())
+        M <<= spb, move_to(i,i), J;
+
+
+    // If typedef was used above the last expression should start
+    // with M <<= spb()...
+
+    // Displaying so that blocks can be easily seen:
+    for (unsigned int i=0; i!=M.size1(); i++) {
+        std::cout << M(i,0);
+        for (unsigned int j=1; j!=M.size2(); j++) std::cout << ", " << M(i,j);
+        std::cout << "\n";
+    }
+    // [ J 0 0 0 ... 0]
+    // [ 0 J 0 0 ... 0]
+    // [ 0 . . . ... 0]
+    // [ 0 0 ... 0 0 J]
+
+
+    // A "repeat" trasverser may by provided so that this becomes faster and an on-liner like:
+    // M <<= spb, repeat(0, size, J.size1(), 0, size, J.size1()), J;
+    // An alternate would be to create a :repeater" matrix and vector expression that can be used in other places as well. The latter is probably better,
+    return 0;
+}
+
diff --git a/doc/samples/banded_adaptor.cpp b/doc/samples/banded_adaptor.cpp
new file mode 100644
index 0000000..8aa5a21
--- /dev/null
+++ b/doc/samples/banded_adaptor.cpp
@@ -0,0 +1,25 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/banded.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    banded_adaptor<matrix<double> > ba (m, 1, 1);
+    for (signed i = 0; i < signed (ba.size1 ()); ++ i)
+        for (signed j = (std::max) (i - 1, 0); j < (std::min) (i + 2, signed (ba.size2 ())); ++ j)
+            ba (i, j) = 3 * i + j;
+    std::cout << ba << std::endl;
+}
+
diff --git a/doc/samples/banded_matrix.cpp b/doc/samples/banded_matrix.cpp
new file mode 100644
index 0000000..73746b7
--- /dev/null
+++ b/doc/samples/banded_matrix.cpp
@@ -0,0 +1,24 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/banded.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    banded_matrix<double> m (3, 3, 1, 1);
+    for (signed i = 0; i < signed (m.size1 ()); ++ i)
+        for (signed j = (std::max) (i - 1, 0); j < (std::min) (i + 2, signed (m.size2 ())); ++ j)
+            m (i, j) = 3 * i + j;
+    std::cout << m << std::endl;
+}
+
diff --git a/doc/samples/bounded_array.cpp b/doc/samples/bounded_array.cpp
new file mode 100644
index 0000000..bc827a3
--- /dev/null
+++ b/doc/samples/bounded_array.cpp
@@ -0,0 +1,23 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/storage.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    bounded_array<double, 3> a (3);
+    for (unsigned i = 0; i < a.size (); ++ i) {
+        a [i] = i;
+        std::cout << a [i] << std::endl;
+    }
+}
+
diff --git a/doc/samples/compressed_matrix.cpp b/doc/samples/compressed_matrix.cpp
new file mode 100644
index 0000000..997106e
--- /dev/null
+++ b/doc/samples/compressed_matrix.cpp
@@ -0,0 +1,24 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    compressed_matrix<double> m (3, 3, 3 * 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i)
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+    std::cout << m << std::endl;
+}
+
diff --git a/doc/samples/compressed_vector.cpp b/doc/samples/compressed_vector.cpp
new file mode 100644
index 0000000..33353e4
--- /dev/null
+++ b/doc/samples/compressed_vector.cpp
@@ -0,0 +1,23 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    compressed_vector<double> v (3, 3);
+    for (unsigned i = 0; i < v.size (); ++ i)
+        v (i) = i;
+    std::cout << v << std::endl;
+}
+
diff --git a/doc/samples/coordinate_matrix.cpp b/doc/samples/coordinate_matrix.cpp
new file mode 100644
index 0000000..ee09515
--- /dev/null
+++ b/doc/samples/coordinate_matrix.cpp
@@ -0,0 +1,24 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    coordinate_matrix<double> m (3, 3, 3 * 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i)
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+    std::cout << m << std::endl;
+}
+
diff --git a/doc/samples/coordinate_vector.cpp b/doc/samples/coordinate_vector.cpp
new file mode 100644
index 0000000..44893fc
--- /dev/null
+++ b/doc/samples/coordinate_vector.cpp
@@ -0,0 +1,23 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    coordinate_vector<double> v (3, 3);
+    for (unsigned i = 0; i < v.size (); ++ i)
+        v (i) = i;
+    std::cout << v << std::endl;
+}
+
diff --git a/doc/samples/ex_triangular.cpp b/doc/samples/ex_triangular.cpp
new file mode 100644
index 0000000..a2a34d9
--- /dev/null
+++ b/doc/samples/ex_triangular.cpp
@@ -0,0 +1,58 @@
+//          Copyright Gunter Winkler 2004 - 2009.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <iostream>
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+
+#include <boost/numeric/ublas/io.hpp>
+
+using std::cout;
+using std::endl;
+
+
+
+namespace ublas = boost::numeric::ublas;
+
+
+int main(int argc, char * argv[] ) {
+
+  ublas::matrix<double> M (3, 3);
+  for (std::size_t i=0; i < M.data().size(); ++i) { M.data()[i] = 1+i ; }
+
+  std::cout << "full         M  = " << M << "\n" ;
+
+  ublas::triangular_matrix<double, ublas::lower> L;
+  ublas::triangular_matrix<double, ublas::unit_lower> UL;
+  ublas::triangular_matrix<double, ublas::strict_lower> SL;
+  
+  L  = ublas::triangular_adaptor<ublas::matrix<double>, ublas::lower> (M);
+  SL = ublas::triangular_adaptor<ublas::matrix<double>, ublas::strict_lower> (M); 
+  UL = ublas::triangular_adaptor<ublas::matrix<double>, ublas::unit_lower> (M);  
+  
+  std::cout << "lower        L  = " << L << "\n" 
+            << "strict lower SL = " << SL << "\n" 
+            << "unit lower   UL = " << UL << "\n" ;
+
+  ublas::triangular_matrix<double, ublas::upper> U;
+  ublas::triangular_matrix<double, ublas::unit_upper> UU;
+  ublas::triangular_matrix<double, ublas::strict_upper> SU;
+  
+  U =  ublas::triangular_adaptor<ublas::matrix<double>, ublas::upper> (M);
+  SU = ublas::triangular_adaptor<ublas::matrix<double>, ublas::strict_upper> (M); 
+  UU = ublas::triangular_adaptor<ublas::matrix<double>, ublas::unit_upper> (M);  
+
+  std::cout << "upper        U  = " << U << "\n" 
+            << "strict upper SU = " << SU << "\n" 
+            << "unit upper   UU = " << UU << "\n" ;
+
+  std::cout << "M = L + SU ? " << ((norm_inf( M - (L + SU) ) == 0.0)?"ok":"failed") << "\n";
+  std::cout << "M = U + SL ? " << ((norm_inf( M - (U + SL) ) == 0.0)?"ok":"failed") << "\n";
+
+}
+
+
diff --git a/doc/samples/hermitian_adaptor.cpp b/doc/samples/hermitian_adaptor.cpp
new file mode 100644
index 0000000..889ae4e
--- /dev/null
+++ b/doc/samples/hermitian_adaptor.cpp
@@ -0,0 +1,34 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/hermitian.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<std::complex<double> > m (3, 3);
+    hermitian_adaptor<matrix<std::complex<double> >, lower> hal (m);
+    for (unsigned i = 0; i < hal.size1 (); ++ i) {
+        for (unsigned j = 0; j < i; ++ j)
+            hal (i, j) = std::complex<double> (3 * i + j, 3 * i + j);
+        hal (i, i) = std::complex<double> (4 * i, 0);
+    }
+    std::cout << hal << std::endl;
+    hermitian_adaptor<matrix<std::complex<double> >, upper> hau (m);
+    for (unsigned i = 0; i < hau.size1 (); ++ i) {
+        hau (i, i) = std::complex<double> (4 * i, 0);
+        for (unsigned j = i + 1; j < hau.size2 (); ++ j)
+            hau (i, j) = std::complex<double> (3 * i + j, 3 * i + j);
+    }
+    std::cout << hau << std::endl;
+}
+
diff --git a/doc/samples/hermitian_matrix.cpp b/doc/samples/hermitian_matrix.cpp
new file mode 100644
index 0000000..1a71ad5
--- /dev/null
+++ b/doc/samples/hermitian_matrix.cpp
@@ -0,0 +1,33 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/hermitian.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    hermitian_matrix<std::complex<double>, lower> ml (3, 3);
+    for (unsigned i = 0; i < ml.size1 (); ++ i) {
+        for (unsigned j = 0; j < i; ++ j)
+            ml (i, j) = std::complex<double> (3 * i + j, 3 * i + j);
+        ml (i, i) = std::complex<double> (4 * i, 0);
+    }
+    std::cout << ml << std::endl;
+    hermitian_matrix<std::complex<double>, upper> mu (3, 3);
+    for (unsigned i = 0; i < mu.size1 (); ++ i) {
+        mu (i, i) = std::complex<double> (4 * i, 0);
+        for (unsigned j = i + 1; j < mu.size2 (); ++ j)
+            mu (i, j) = std::complex<double> (3 * i + j, 3 * i + j);
+    }
+    std::cout << mu << std::endl;
+}
+
diff --git a/doc/samples/identity_matrix.cpp b/doc/samples/identity_matrix.cpp
new file mode 100644
index 0000000..0e98683
--- /dev/null
+++ b/doc/samples/identity_matrix.cpp
@@ -0,0 +1,21 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    identity_matrix<double> m (3);
+    std::cout << m << std::endl;
+}
+
diff --git a/doc/samples/map_array.cpp b/doc/samples/map_array.cpp
new file mode 100644
index 0000000..12dc519
--- /dev/null
+++ b/doc/samples/map_array.cpp
@@ -0,0 +1,24 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/storage_sparse.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    map_array<int, double> a;
+    a.reserve (3);
+    for (unsigned i = 0; i < 3; ++ i) {
+        a [i] = i;
+        std::cout << a [i] << std::endl;
+    }
+}
+
diff --git a/doc/samples/mapped_matrix.cpp b/doc/samples/mapped_matrix.cpp
new file mode 100644
index 0000000..92b5ca7
--- /dev/null
+++ b/doc/samples/mapped_matrix.cpp
@@ -0,0 +1,24 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    mapped_matrix<double> m (3, 3, 3 * 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i)
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+    std::cout << m << std::endl;
+}
+
diff --git a/doc/samples/mapped_vector.cpp b/doc/samples/mapped_vector.cpp
new file mode 100644
index 0000000..73e6d8f
--- /dev/null
+++ b/doc/samples/mapped_vector.cpp
@@ -0,0 +1,23 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    mapped_vector<double> v (3, 3);
+    for (unsigned i = 0; i < v.size (); ++ i)
+        v (i) = i;
+    std::cout << v << std::endl;
+}
+
diff --git a/doc/samples/matrix.cpp b/doc/samples/matrix.cpp
new file mode 100644
index 0000000..63d3c7d
--- /dev/null
+++ b/doc/samples/matrix.cpp
@@ -0,0 +1,24 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i)
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+    std::cout << m << std::endl;
+}
+
diff --git a/doc/samples/matrix_binary.cpp b/doc/samples/matrix_binary.cpp
new file mode 100644
index 0000000..66edf62
--- /dev/null
+++ b/doc/samples/matrix_binary.cpp
@@ -0,0 +1,26 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m1 (3, 3), m2 (3, 3);
+    for (unsigned i = 0; i < (std::min) (m1.size1 (), m2.size1 ()); ++ i)
+        for (unsigned j = 0; j < (std::min) (m1.size2 (), m2.size2 ()); ++ j)
+            m1 (i, j) = m2 (i, j) = 3 * i + j;
+
+    std::cout << m1 + m2 << std::endl;
+    std::cout << m1 - m2 << std::endl;
+}
+
diff --git a/doc/samples/matrix_binary_scalar.cpp b/doc/samples/matrix_binary_scalar.cpp
new file mode 100644
index 0000000..fb3282f
--- /dev/null
+++ b/doc/samples/matrix_binary_scalar.cpp
@@ -0,0 +1,26 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i)
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+
+    std::cout << 2.0 * m << std::endl;
+    std::cout << m * 2.0 << std::endl;
+}
+
diff --git a/doc/samples/matrix_column.cpp b/doc/samples/matrix_column.cpp
new file mode 100644
index 0000000..9eb0ca4
--- /dev/null
+++ b/doc/samples/matrix_column.cpp
@@ -0,0 +1,27 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    for (unsigned j = 0; j < m.size2 (); ++ j) {
+        matrix_column<matrix<double> > mc (m, j);
+        for (unsigned i = 0; i < mc.size (); ++ i)
+            mc (i) = 3 * i + j;
+        std::cout << mc << std::endl;
+    }
+}
+
diff --git a/doc/samples/matrix_column_project.cpp b/doc/samples/matrix_column_project.cpp
new file mode 100644
index 0000000..d2585c6
--- /dev/null
+++ b/doc/samples/matrix_column_project.cpp
@@ -0,0 +1,26 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    for (unsigned j = 0; j < m.size2 (); ++ j) {
+        for (unsigned i = 0; i < m.size1 (); ++ i)
+            column (m, j) (i) = 3 * i + j;
+        std::cout << column (m, j) << std::endl;
+    }
+}
+
diff --git a/doc/samples/matrix_matrix_binary.cpp b/doc/samples/matrix_matrix_binary.cpp
new file mode 100644
index 0000000..17e33a6
--- /dev/null
+++ b/doc/samples/matrix_matrix_binary.cpp
@@ -0,0 +1,25 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m1 (3, 3), m2 (3, 3);
+    for (unsigned i = 0; i < (std::min) (m1.size1 (), m2.size1 ()); ++ i)
+        for (unsigned j = 0; j < (std::min) (m1.size2 (), m2.size2 ()); ++ j)
+            m1 (i, j) = m2 (i, j) = 3 * i + j;
+
+    std::cout << prod (m1, m2) << std::endl;
+}
+
diff --git a/doc/samples/matrix_matrix_solve.cpp b/doc/samples/matrix_matrix_solve.cpp
new file mode 100644
index 0000000..07d05a3
--- /dev/null
+++ b/doc/samples/matrix_matrix_solve.cpp
@@ -0,0 +1,25 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m1 (3, 3), m2 (3, 3);
+    for (unsigned i = 0; i < (std::min) (m1.size1 (), m2.size1 ()); ++ i)
+        for (unsigned j = 0; j <= i; ++ j)
+            m1 (i, j) = m2 (i, j) = 3 * i + j + 1;
+
+    std::cout << solve (m1, m2, lower_tag ()) << std::endl;
+}
+
diff --git a/doc/samples/matrix_range.cpp b/doc/samples/matrix_range.cpp
new file mode 100644
index 0000000..048ab9f
--- /dev/null
+++ b/doc/samples/matrix_range.cpp
@@ -0,0 +1,26 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    matrix_range<matrix<double> > mr (m, range (0, 3), range (0, 3));
+    for (unsigned i = 0; i < mr.size1 (); ++ i)
+        for (unsigned j = 0; j < mr.size2 (); ++ j)
+            mr (i, j) = 3 * i + j;
+    std::cout << mr << std::endl;
+}
+
diff --git a/doc/samples/matrix_range_project.cpp b/doc/samples/matrix_range_project.cpp
new file mode 100644
index 0000000..3ee095c
--- /dev/null
+++ b/doc/samples/matrix_range_project.cpp
@@ -0,0 +1,25 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i)
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            project (m, range (0, 3), range (0, 3)) (i, j) = 3 * i + j;
+    std::cout << project (m, range (0, 3), range (0, 3)) << std::endl;
+}
+
diff --git a/doc/samples/matrix_row.cpp b/doc/samples/matrix_row.cpp
new file mode 100644
index 0000000..156c1f5
--- /dev/null
+++ b/doc/samples/matrix_row.cpp
@@ -0,0 +1,27 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i) {
+        matrix_row<matrix<double> > mr (m, i);
+        for (unsigned j = 0; j < mr.size (); ++ j)
+            mr (j) = 3 * i + j;
+        std::cout << mr << std::endl;
+    }
+}
+
diff --git a/doc/samples/matrix_row_project.cpp b/doc/samples/matrix_row_project.cpp
new file mode 100644
index 0000000..6cc3569
--- /dev/null
+++ b/doc/samples/matrix_row_project.cpp
@@ -0,0 +1,26 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i) {
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            row (m, i) (j) = 3 * i + j;
+        std::cout << row (m, i) << std::endl;
+    }
+}
+
diff --git a/doc/samples/matrix_slice.cpp b/doc/samples/matrix_slice.cpp
new file mode 100644
index 0000000..d3911f6
--- /dev/null
+++ b/doc/samples/matrix_slice.cpp
@@ -0,0 +1,26 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    matrix_slice<matrix<double> > ms (m, slice (0, 1, 3), slice (0, 1, 3));
+    for (unsigned i = 0; i < ms.size1 (); ++ i)
+        for (unsigned j = 0; j < ms.size2 (); ++ j)
+            ms (i, j) = 3 * i + j;
+    std::cout << ms << std::endl;
+}
+
diff --git a/doc/samples/matrix_slice_project.cpp b/doc/samples/matrix_slice_project.cpp
new file mode 100644
index 0000000..0b6150a
--- /dev/null
+++ b/doc/samples/matrix_slice_project.cpp
@@ -0,0 +1,25 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i)
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            project (m, slice (0, 1, 3), slice (0, 1, 3)) (i, j) = 3 * i + j;
+    std::cout << project (m, slice (0, 1, 3), slice (0, 1, 3)) << std::endl;
+}
+
diff --git a/doc/samples/matrix_unary.cpp b/doc/samples/matrix_unary.cpp
new file mode 100644
index 0000000..044b294
--- /dev/null
+++ b/doc/samples/matrix_unary.cpp
@@ -0,0 +1,30 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<std::complex<double> > m (3, 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i)
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            m (i, j) = std::complex<double> (3 * i + j, 3 * i + j);
+
+    std::cout << - m << std::endl;
+    std::cout << conj (m) << std::endl;
+    std::cout << real (m) << std::endl;
+    std::cout << imag (m) << std::endl;
+    std::cout << trans (m) << std::endl;
+    std::cout << herm (m) << std::endl;
+}
+
diff --git a/doc/samples/matrix_vector_binary.cpp b/doc/samples/matrix_vector_binary.cpp
new file mode 100644
index 0000000..a53665b
--- /dev/null
+++ b/doc/samples/matrix_vector_binary.cpp
@@ -0,0 +1,29 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    vector<double> v (3);
+    for (unsigned i = 0; i < (std::min) (m.size1 (), v.size ()); ++ i) {
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+        v (i) = i;
+    }
+
+    std::cout << prod (m, v) << std::endl;
+    std::cout << prod (v, m) << std::endl;
+}
+
diff --git a/doc/samples/matrix_vector_range.cpp b/doc/samples/matrix_vector_range.cpp
new file mode 100644
index 0000000..3a4c7e7
--- /dev/null
+++ b/doc/samples/matrix_vector_range.cpp
@@ -0,0 +1,27 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i)
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+
+    matrix_vector_range<matrix<double> > mvr (m, range (0, 3), range (0, 3));
+    std::cout << mvr << std::endl;
+}
+
diff --git a/doc/samples/matrix_vector_slice.cpp b/doc/samples/matrix_vector_slice.cpp
new file mode 100644
index 0000000..335c06c
--- /dev/null
+++ b/doc/samples/matrix_vector_slice.cpp
@@ -0,0 +1,27 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    for (unsigned i = 0; i < m.size1 (); ++ i)
+        for (unsigned j = 0; j < m.size2 (); ++ j)
+            m (i, j) = 3 * i + j;
+
+    matrix_vector_slice<matrix<double> > mvs (m, slice (0, 1, 3), slice (0, 1, 3));
+    std::cout << mvs << std::endl;
+}
+
diff --git a/doc/samples/matrix_vector_solve.cpp b/doc/samples/matrix_vector_solve.cpp
new file mode 100644
index 0000000..819856f
--- /dev/null
+++ b/doc/samples/matrix_vector_solve.cpp
@@ -0,0 +1,29 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    vector<double> v (3);
+    for (unsigned i = 0; i < (std::min) (m.size1 (), v.size ()); ++ i) {
+        for (unsigned j = 0; j <= i; ++ j)
+            m (i, j) = 3 * i + j + 1;
+        v (i) = i;
+    }
+
+    std::cout << solve (m, v, lower_tag ()) << std::endl;
+    std::cout << solve (v, m, lower_tag ()) << std::endl;
+}
+
diff --git a/doc/samples/range.cpp b/doc/samples/range.cpp
new file mode 100644
index 0000000..35526ff
--- /dev/null
+++ b/doc/samples/range.cpp
@@ -0,0 +1,22 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/storage.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    range r (0, 3);
+    for (unsigned i = 0; i < r.size (); ++ i) {
+        std::cout << r (i) << std::endl;
+    }
+}
+
diff --git a/doc/samples/slice.cpp b/doc/samples/slice.cpp
new file mode 100644
index 0000000..394251e
--- /dev/null
+++ b/doc/samples/slice.cpp
@@ -0,0 +1,22 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/storage.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    slice s (0, 1, 3);
+    for (unsigned i = 0; i < s.size (); ++ i) {
+        std::cout << s (i) << std::endl;
+    }
+}
+
diff --git a/doc/samples/symmetric_adaptor.cpp b/doc/samples/symmetric_adaptor.cpp
new file mode 100644
index 0000000..4a3f67c
--- /dev/null
+++ b/doc/samples/symmetric_adaptor.cpp
@@ -0,0 +1,30 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/symmetric.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    symmetric_adaptor<matrix<double>, lower> sal (m);
+    for (unsigned i = 0; i < sal.size1 (); ++ i)
+        for (unsigned j = 0; j <= i; ++ j)
+            sal (i, j) = 3 * i + j;
+    std::cout << sal << std::endl;
+    symmetric_adaptor<matrix<double>, upper> sau (m);
+    for (unsigned i = 0; i < sau.size1 (); ++ i)
+        for (unsigned j = i; j < sau.size2 (); ++ j)
+            sau (i, j) = 3 * i + j;
+    std::cout << sau << std::endl;
+}
+
diff --git a/doc/samples/symmetric_matrix.cpp b/doc/samples/symmetric_matrix.cpp
new file mode 100644
index 0000000..c9bed51
--- /dev/null
+++ b/doc/samples/symmetric_matrix.cpp
@@ -0,0 +1,29 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/symmetric.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    symmetric_matrix<double, lower> ml (3, 3);
+    for (unsigned i = 0; i < ml.size1 (); ++ i)
+        for (unsigned j = 0; j <= i; ++ j)
+            ml (i, j) = 3 * i + j;
+    std::cout << ml << std::endl;
+    symmetric_matrix<double, upper> mu (3, 3);
+    for (unsigned i = 0; i < mu.size1 (); ++ i)
+        for (unsigned j = i; j < mu.size2 (); ++ j)
+            mu (i, j) = 3 * i + j;
+    std::cout << mu << std::endl;
+}
+
diff --git a/doc/samples/triangular_adaptor.cpp b/doc/samples/triangular_adaptor.cpp
new file mode 100644
index 0000000..7f7647e
--- /dev/null
+++ b/doc/samples/triangular_adaptor.cpp
@@ -0,0 +1,30 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix<double> m (3, 3);
+    triangular_adaptor<matrix<double>, lower> tal (m);
+    for (unsigned i = 0; i < tal.size1 (); ++ i)
+        for (unsigned j = 0; j <= i; ++ j)
+            tal (i, j) = 3 * i + j;
+    std::cout << tal << std::endl;
+    triangular_adaptor<matrix<double>, upper> tau (m);
+    for (unsigned i = 0; i < tau.size1 (); ++ i)
+        for (unsigned j = i; j < tau.size2 (); ++ j)
+            tau (i, j) = 3 * i + j;
+    std::cout << tau << std::endl;
+}
+
diff --git a/doc/samples/triangular_matrix.cpp b/doc/samples/triangular_matrix.cpp
new file mode 100644
index 0000000..9177233
--- /dev/null
+++ b/doc/samples/triangular_matrix.cpp
@@ -0,0 +1,29 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    triangular_matrix<double, lower> ml (3, 3);
+    for (unsigned i = 0; i < ml.size1 (); ++ i)
+        for (unsigned j = 0; j <= i; ++ j)
+            ml (i, j) = 3 * i + j;
+    std::cout << ml << std::endl;
+    triangular_matrix<double, upper> mu (3, 3);
+    for (unsigned i = 0; i < mu.size1 (); ++ i)
+        for (unsigned j = i; j < mu.size2 (); ++ j)
+            mu (i, j) = 3 * i + j;
+    std::cout << mu << std::endl;
+}
+
diff --git a/doc/samples/unbounded_array.cpp b/doc/samples/unbounded_array.cpp
new file mode 100644
index 0000000..2331f57
--- /dev/null
+++ b/doc/samples/unbounded_array.cpp
@@ -0,0 +1,23 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/storage.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    unbounded_array<double> a (3);
+    for (unsigned i = 0; i < a.size (); ++ i) {
+        a [i] = i;
+        std::cout << a [i] << std::endl;
+    }
+}
+
diff --git a/doc/samples/unit_vector.cpp b/doc/samples/unit_vector.cpp
new file mode 100644
index 0000000..63fc825
--- /dev/null
+++ b/doc/samples/unit_vector.cpp
@@ -0,0 +1,23 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    for (int i = 0; i < 3; ++ i) {
+        unit_vector<double> v (3, i);
+        std::cout << v << std::endl;
+    }
+}
+
diff --git a/doc/samples/vector.cpp b/doc/samples/vector.cpp
new file mode 100644
index 0000000..1f8310c
--- /dev/null
+++ b/doc/samples/vector.cpp
@@ -0,0 +1,23 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<double> v (3);
+    for (unsigned i = 0; i < v.size (); ++ i)
+        v (i) = i;
+    std::cout << v << std::endl;
+}
+
diff --git a/doc/samples/vector_binary.cpp b/doc/samples/vector_binary.cpp
new file mode 100644
index 0000000..8b42d06
--- /dev/null
+++ b/doc/samples/vector_binary.cpp
@@ -0,0 +1,25 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<double> v1 (3), v2 (3);
+    for (unsigned i = 0; i < (std::min) (v1.size (), v2.size ()); ++ i)
+        v1 (i) = v2 (i) = i;
+
+    std::cout << v1 + v2 << std::endl;
+    std::cout << v1 - v2 << std::endl;
+}
+
diff --git a/doc/samples/vector_binary_outer.cpp b/doc/samples/vector_binary_outer.cpp
new file mode 100644
index 0000000..094a0a9
--- /dev/null
+++ b/doc/samples/vector_binary_outer.cpp
@@ -0,0 +1,24 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<double> v1 (3), v2 (3);
+    for (unsigned i = 0; i < (std::min) (v1.size (), v2.size ()); ++ i)
+        v1 (i) = v2 (i) = i;
+
+    std::cout << outer_prod (v1, v2) << std::endl;
+}
+
diff --git a/doc/samples/vector_binary_redux.cpp b/doc/samples/vector_binary_redux.cpp
new file mode 100644
index 0000000..abc3641
--- /dev/null
+++ b/doc/samples/vector_binary_redux.cpp
@@ -0,0 +1,23 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<double> v1 (3), v2 (3);
+    for (unsigned i = 0; i < (std::min) (v1.size (), v2.size ()); ++ i)
+        v1 (i) = v2 (i) = i;
+
+    std::cout << inner_prod (v1, v2) << std::endl;
+}
+
diff --git a/doc/samples/vector_binary_scalar.cpp b/doc/samples/vector_binary_scalar.cpp
new file mode 100644
index 0000000..8f853e5
--- /dev/null
+++ b/doc/samples/vector_binary_scalar.cpp
@@ -0,0 +1,25 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<double> v (3);
+    for (unsigned i = 0; i < v.size (); ++ i)
+        v (i) = i;
+
+    std::cout << 2.0 * v << std::endl;
+    std::cout << v * 2.0 << std::endl;
+}
+
diff --git a/doc/samples/vector_range.cpp b/doc/samples/vector_range.cpp
new file mode 100644
index 0000000..bf48c23
--- /dev/null
+++ b/doc/samples/vector_range.cpp
@@ -0,0 +1,25 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<double> v (3);
+    vector_range<vector<double> > vr (v, range (0, 3));
+    for (unsigned i = 0; i < vr.size (); ++ i)
+        vr (i) = i;
+    std::cout << vr << std::endl;
+}
+
diff --git a/doc/samples/vector_range_project.cpp b/doc/samples/vector_range_project.cpp
new file mode 100644
index 0000000..ebe3481
--- /dev/null
+++ b/doc/samples/vector_range_project.cpp
@@ -0,0 +1,24 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<double> v (3);
+    for (int i = 0; i < 3; ++ i)
+        project (v, range (0, 3)) (i) = i;
+    std::cout << project (v, range (0, 3)) << std::endl;
+}
+
diff --git a/doc/samples/vector_slice.cpp b/doc/samples/vector_slice.cpp
new file mode 100644
index 0000000..478631b
--- /dev/null
+++ b/doc/samples/vector_slice.cpp
@@ -0,0 +1,25 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<double> v (3);
+    vector_slice<vector<double> > vs (v, slice (0, 1, 3));
+    for (unsigned i = 0; i < vs.size (); ++ i)
+        vs (i) = i;
+    std::cout << vs << std::endl;
+}
+
diff --git a/doc/samples/vector_slice_project.cpp b/doc/samples/vector_slice_project.cpp
new file mode 100644
index 0000000..a8f1794
--- /dev/null
+++ b/doc/samples/vector_slice_project.cpp
@@ -0,0 +1,24 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<double> v (3);
+    for (int i = 0; i < 3; ++ i)
+        project (v, slice (0, 1, 3)) (i) = i;
+    std::cout << project (v, slice (0, 1, 3)) << std::endl;
+}
+
diff --git a/doc/samples/vector_unary.cpp b/doc/samples/vector_unary.cpp
new file mode 100644
index 0000000..4d9a8b5
--- /dev/null
+++ b/doc/samples/vector_unary.cpp
@@ -0,0 +1,29 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<std::complex<double> > v (3);
+    for (unsigned i = 0; i < v.size (); ++ i)
+        v (i) = std::complex<double> (i, i);
+
+    std::cout << - v << std::endl;
+    std::cout << conj (v) << std::endl;
+    std::cout << real (v) << std::endl;
+    std::cout << imag (v) << std::endl;
+    std::cout << trans (v) << std::endl;
+    std::cout << herm (v) << std::endl;
+}
+
diff --git a/doc/samples/vector_unary_redux.cpp b/doc/samples/vector_unary_redux.cpp
new file mode 100644
index 0000000..7de1918
--- /dev/null
+++ b/doc/samples/vector_unary_redux.cpp
@@ -0,0 +1,27 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector<double> v (3);
+    for (unsigned i = 0; i < v.size (); ++ i)
+        v (i) = i;
+
+    std::cout << sum (v) << std::endl;
+    std::cout << norm_1 (v) << std::endl;
+    std::cout << norm_2 (v) << std::endl;
+    std::cout << norm_inf (v) << std::endl;
+    std::cout << index_norm_inf (v) << std::endl;
+}
+
diff --git a/doc/samples/zero_matrix.cpp b/doc/samples/zero_matrix.cpp
new file mode 100644
index 0000000..fbdd8d6
--- /dev/null
+++ b/doc/samples/zero_matrix.cpp
@@ -0,0 +1,21 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    zero_matrix<double> m (3, 3);
+    std::cout << m << std::endl;
+}
+
diff --git a/doc/samples/zero_vector.cpp b/doc/samples/zero_vector.cpp
new file mode 100644
index 0000000..7a4d77d
--- /dev/null
+++ b/doc/samples/zero_vector.cpp
@@ -0,0 +1,21 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+int main () {
+    using namespace boost::numeric::ublas;
+    zero_vector<double> v (3);
+    std::cout << v << std::endl;
+}
+
diff --git a/doc/storage_concept.html b/doc/storage_concept.html
new file mode 100644
index 0000000..2f30529
--- /dev/null
+++ b/doc/storage_concept.html
@@ -0,0 +1,157 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Storage concept</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Storage concept</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="range"></a>Storage concept</h2>
+<h4>Description</h4>
+<p>Storage is a variable-size container whose elements are arranged in a strict linear order.
+<p>Storage extends the STL Container concept with some STL Sequence-like functionality. The main difference with
+the Sequence concept however is that the Storage concept does not require default-initialisation of its
+elements.
+<h4>Refinement of</h4>
+<a href="http://www.sgi.com/tech/stl/RandomAccessContainer.html">Random Access Container</a>
+and 
+<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default Constructible</a>
+<h4>Associated types</h4>
+No additional types beyond those defined by 
+<a href="http://www.sgi.com/tech/stl/RandomAccessContainer.html">Random Access Container</a>
+<h4>Notation</h4>
+<table summary="storage types">
+<tr><td><tt>X</tt></td><td>A type that is model of Storage</td></tr>
+<tr><td><tt>T</tt></td><td>The value_type of <tt>X</tt></td></tr>
+<tr><td><tt>t</tt></td><td>An object of type <tt>T</tt></td></tr>
+<tr><td><tt>n</tt></td><td>object of type convertible to <tt>X::size_type</tt></td></tr>
+</table>
+<h4>Definitions</h4>
+<h4>Valid expressions</h4>
+In addition to the expressions defined in 
+<a href="http://www.sgi.com/tech/stl/RandomAccessContainer.html">Random Access Container</a>,
+and 
+<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default Constructible</a>
+the following expressions must be valid:
+<table border="1" summary="type requirements">
+<TR><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></TR>
+<TR>
+<td>Size constructor</td>
+<td><tt>X(n)</tt></td>
+<td>T is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">DefaultConstructible</a></td>
+<td><tt>X</tt></td>
+</TR>
+<TR>
+<td>Fill constructor</td>
+<td><tt>X(n,t)</tt></td>
+<td></td>
+<td><tt>X</tt></td>
+</TR>
+<TR>
+<TD>Range constructor</TD>
+<TD><tt>X(i, j)</tt></TD>
+<TD><tt>i</tt> and <tt>j</tt> are <A href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterators</A> whose value type is convertible to <tt>T</tt> </TD>
+<TD><tt>X</tt> </TD>
+</TR>
+<TR>
+<TD>Resize</TD>
+<TD><tt>a.resize(n, t)</tt></TD>
+<TD><tt>a</tt> is mutable</TD>
+<TD><tt>void</tt></TD>
+</TR>
+<TR>
+<TD>Resize</TD>
+<TD><tt>a.resize(n)</tt></TD>
+<TD><tt>a</tt> is mutable</TD>
+<TD><tt>void</tt></TD>
+</tr>
+</table>
+<h3>Expression semantics</h3>
+<table border="1" summary="expresisons">
+<tr><th>Name<th>Expression<th>Precondition<th>Semantics<th>Postcondition
+<tr>
+<td>Default-constructor</td>
+<td><tt>X()</tt>
+<td></td>
+<td>Creates 0 elements. 
+</td>
+<td><tt>size()==0</tt></td>
+</tr>
+<tr>
+<td>Size-constructor</td>
+<td><tt>X(n)</tt>
+<td><tt>n>=0</tt></td>
+<td>Creates n elements. Elements are constructed without an initializer. That is
+if T is a (possibly cv-qualified) non-POD class type (or array thereof), the object is default
+initialized. Otherwise, the object created has indeterminate value. See the sentance
+"If new initializer is omitted" in section 5.3.4 paragraph 15 of the ISO C++ standard.
+</td>
+<td><tt>size()==n</tt></td>
+</tr>
+<tr>
+<td>Fill-constructor</td>
+<td><tt>X(n,t)</tt>
+<td><tt>n>=0</tt></td>
+<td>Creates n initialised element with copies of <code>t</code></td>
+<td><tt>size()==n</tt></td>
+</tr>
+<TR>
+<TD>Range constructor</TD>
+<TD><tt>X(i, j)</tt></TD>
+<TD><tt>[i,j)</tt> is a valid range.</TD>
+<TD>copies the range <tt>[i,j) to the storage</tt></TD>
+<TD><tt>size()</tt> is equal to the distance from <tt>i</tt> to <tt>j</tt>.  Each element is a copy of the corresponding element in the range <tt>[i,j)</tt>.</TD>
+</TR>
+<TR>
+<TD>Resize</TD>
+<TD><tt>a.resize(n, t)</tt></TD>
+<TD><tt>n &lt;= a.max_size()</tt></TD>
+<td>Modified the container so that it has exactly <tt>n</tt> elements.<br />
+The container may be reallocated if its size changes.
+Existing element values are preserved, additional elements are copies of <code>t</code>.</td>
+<TD><tt>a.size() == n</tt></TD>
+</TR>
+<TR>
+<TD>Resize</TD>
+<TD><tt>a.resize(n)</tt></TD>
+<TD><tt>n &lt;= a.max_size()</tt></TD>
+<TD>Modified the container so that it has exactly <tt>n</tt> elements.<br />
+The container may be reallocated if its size changes. Element values are uninitialised. That is,
+each element value may be a previously assigned value or default construced value for <code>T</code>.</TD>
+<TD><tt>a.size() == n</tt></TD>
+</tr>
+</table>
+<h4>Complexity guarantees</h4>
+<h4>Invariants</h4>
+<h4>Models</h4>
+<ul>
+<li><a href="unbounded_array.html">unbounded_array</a>
+<li><a href="bounded_array.html">bounded_array</a>
+</ul>
+<h4>Notes</h4>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/storage_sparse.html b/doc/storage_sparse.html
new file mode 100644
index 0000000..b4899d9
--- /dev/null
+++ b/doc/storage_sparse.html
@@ -0,0 +1,288 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Sparse Storage</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Sparse Storage</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="map_std"></a>Default Standard Map</h2>
+<h4>Description</h4>
+<p>The templated class <code>map_std&lt;I, T, ALLOC&gt;</code> provides a
+wrapper for the standard library associative container
+<code>std::map</code>. The wrapper has one simple purpose. It
+allows the definition of a default template parameter (for the
+adapted array) when declaring the sparse container types.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/storage_sparse.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    map_std&lt;int, double&gt; a (3);
+    for (unsigned i = 0; i &lt; a.size (); ++ i) {
+        a [i] = i;
+        std::cout &lt;&lt; a [i] &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header storage_sparse.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>I</code></td>
+<td>The type of index stored in the array.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the array.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>ALLOC</code></td>
+<td>An STL Allocator</td>
+<td>std::allocator</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p>Reversible Container.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of Reversible
+Container.</p>
+<h4>Public base classes</h4>
+<p>std::map</p>
+<h2><a name="map_array"></a>Map Array</h2>
+<h4>Description</h4>
+<p>The templated class <code>map_array&lt;I, T, ALLOC&gt;</code> implements a <code>std::map</code> like associative container as a sorted array. It therefore some of the Associative Container interface without having the same semantics as an std::map.
+<p>At any time the <code>map_array</code> has a capacity up to which new element can be inserted.
+If <code>insert</code> would cause the size of the <code>map_array</code> to exceeds its capactity then it is <strong>reallocated</strong>. Iterators and reference are invalidated.
+The capacity can be directly control using the <code>reserve</code> member function.
+</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/storage_sparse.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    map_array&lt;int, double&gt; a (3);
+    for (unsigned i = 0; i &lt; a.size (); ++ i) {
+        a [i] = i;
+        std::cout &lt;&lt; a [i] &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header storage_sparse.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>I</code></td>
+<td>The type of index stored in the array.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the array.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>ALLOC</code></td>
+<td>An STL Allocator</td>
+<td>std::allocator</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p>Reversible Container.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of Reversible
+Container.</p>
+<h4>Public base classes</h4>
+<p>None.</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>map_array (ALLOC &amp;a = ALLOC())</code></td>
+<td>Allocates a <code>map_array</code> that holds at most zero
+elements.</td>
+</tr>
+<tr>
+<td><code>map_array (const map_array &amp;c)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>~map_array ()</code></td>
+<td>Deallocates the <code>map_array</code> itself.</td>
+</tr>
+<tr>
+<td><code>void reserve (size_type capacity)</code></td>
+<td>
+Changes the<code>map_array</code> capacity. It can hold at most<code>capacity</code> elements without reallocation. The capacity can be reduced such that <code>capacity >= size()</code>. The content of the<code>map_array</code> is preserved.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the <code>map_array</code>.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the capacity of the <code>map_array</code>.</td>
+</tr>
+<tr>
+<td><code>data_reference operator [] (index_type i)</code></td>
+<td>Returns a reference of the element that is associated with a
+particular index. If the <code>map_array</code> does not already
+contain such an element, <code>operator[]</code> inserts the
+default <code>T ()</code>.</td>
+</tr>
+<tr>
+<td><code>map_array &amp;operator = (const map_array
+&amp;a)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>map_array &amp;assign_temporary (map_array
+&amp;a)</code></td>
+<td>Assigns a temporary. May change the array <code>a</code>.</td>
+</tr>
+<tr>
+<td><code>void swap (map_array &amp;a)</code></td>
+<td>Swaps the contents of the arrays.</td>
+</tr>
+<tr>
+<td><code>std::pair<iterator, bool> insert (const value_type
+&amp;p)</code></td>
+<td>Inserts <code>p</code> into the array. The second part of the return value is <code>true</code>
+if <code>p</code> was inserted and <code>false</code> if was not inserted because it was aleady
+present.</td>
+</tr>
+<tr>
+<td><code>iterator insert (iterator it, const value_type
+&amp;p)</code></td>
+<td>Inserts <code>p</code> into the array, using <code>it</code> as
+a hint to where it will be inserted.</td>
+</tr>
+<tr>
+<td><code>void erase (iterator it)</code></td>
+<td>Erases the value at <code>it</code>.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the array.</td>
+</tr>
+<tr>
+<td><code>const_iterator find (index_type i) const</code></td>
+<td>Finds an element whose index is <code>i</code>.</td>
+</tr>
+<tr>
+<td><code>iterator find (index_type i)</code></td>
+<td>Finds an element whose index is <code>i</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator lower_bound (index_type i)
+const</code></td>
+<td>Finds the first element whose index is not less than
+<code>i</code> .</td>
+</tr>
+<tr>
+<td><code>iterator lower_bound (index_type i)</code></td>
+<td>Finds the first element whose index is not less than
+<code>i</code> .</td>
+</tr>
+<tr>
+<td><code>const_iterator upper_bound (index_type i)
+const</code></td>
+<td>Finds the first element whose index is greater than
+<code>i</code> .</td>
+</tr>
+<tr>
+<td><code>iterator upper_bound (index_type i)</code></td>
+<td>Finds the first element whose index is greater than
+<code>i</code> .</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>map_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>map_array</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>map_array</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>map_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>map_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>map_array</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>map_array</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>map_array</code>.</td>
+</tr>
+</tbody>
+</table>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/symmetric.html b/doc/symmetric.html
new file mode 100644
index 0000000..c3693bd
--- /dev/null
+++ b/doc/symmetric.html
@@ -0,0 +1,588 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Symmetric Matrix</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Symmetric Matrix</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="symmetric_matrix"></a>Symmetric Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>symmetric_matrix&lt;T, F1, F2,
+A&gt;</code> is the base container adaptor for symmetric matrices.
+For a <em>(n x n</em> )-dimensional symmetric matrix and <em>0
+&lt;= i &lt; n</em>, <em>0 &lt;= j &lt; n</em> holds
+<em>s</em><sub><em>i, j</em></sub> <em>= s</em><sub><em>j,
+i</em></sub>. The storage of symmetric matrices is packed.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/symmetric.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    symmetric_matrix&lt;double, lower&gt; ml (3, 3);
+    for (unsigned i = 0; i &lt; ml.size1 (); ++ i)
+        for (unsigned j = 0; j &lt;= i; ++ j)
+            ml (i, j) = 3 * i + j;
+    std::cout &lt;&lt; ml &lt;&lt; std::endl;
+    symmetric_matrix&lt;double, upper&gt; mu (3, 3);
+    for (unsigned i = 0; i &lt; mu.size1 (); ++ i)
+        for (unsigned j = i; j &lt; mu.size2 (); ++ j)
+            mu (i, j) = 3 * i + j;
+    std::cout &lt;&lt; mu &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header symmetric.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F1</code></td>
+<td>Functor describing the type of the symmetric matrix. <a name=
+"#symmetric_matrix_1">[1]</a></td>
+<td><code>lower</code></td>
+</tr>
+<tr>
+<td><code>F2</code></td>
+<td>Functor describing the storage organization. <a name=
+"#symmetric_matrix_2">[2]</a></td>
+<td><code>row_major</code></td>
+</tr>
+<tr>
+<td><code>A</code></td>
+<td>The type of the adapted array. <a name="#symmetric_matrix_3"
+>[3]</a></td>
+<td><code>unbounded_array&lt;T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;symmetric_matrix&lt;T, F1, F2, A&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>symmetric_matrix (size_type size)</code></td>
+<td>Allocates an uninitialized <code>symmetric_matrix</code> that
+holds <code>size</code> rows of <code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>symmetric_matrix (const symmetric_matrix
+&amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_matrix (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, bool preserve =
+true)</code></td>
+<td>Reallocates a <code>symmetric_matrix</code> to hold
+<code>size</code> rows of <code>size</code> elements. The existing
+elements of the <code>symmetric_matrix</code> are preseved when
+specified.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns a <code>const</code> reference of the <code>j</code>
+-th element in the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>symmetric_matrix &amp;operator = (const symmetric_matrix
+&amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>symmetric_matrix &amp;assign_temporary (symmetric_matrix
+&amp;m)</code></td>
+<td>Assigns a temporary. May change the symmetric matrix
+<code>m</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_matrix &amp;operator = (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_matrix &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the symmetric matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_matrix &amp;operator += (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the symmetric matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_matrix &amp;plus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a matrix expression to the symmetric matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_matrix &amp;operator -= (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the symmetric matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_matrix &amp;minus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a matrix expression from the symmetric matrix. Left
+and right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+symmetric_matrix &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the symmetric matrix
+with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+symmetric_matrix &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the symmetric matrix
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (symmetric_matrix &amp;m)</code></td>
+<td>Swaps the contents of the symmetric matrices.</td>
+</tr>
+<tr>
+<td><code>void insert (size_type i, size_type j, const_reference
+t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>j</code>-th
+element of the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void erase (size_type i, size_type j)</code></td>
+<td>Erases the value at the <code>j</code>-th elemenst of the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the matrix.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>symmetric_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>symmetric_matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="symmetric_matrix_1">[1]</a>
+Supported parameters for the type of the symmetric matrix are
+<code>lower</code> and <code>upper</code>.</p>
+<p><a name="symmetric_matrix_2">[2]</a>
+Supported parameters for the storage organization are
+<code>row_major</code> and <code>column_major</code>.</p>
+<p><a name="symmetric_matrix_3">[3]</a>
+Supported parameters for the adapted array are
+<code>unbounded_array&lt;T&gt;</code> ,
+<code>bounded_array&lt;T&gt;</code> and
+<code>std::vector&lt;T&gt;</code> .</p>
+<h2><a name="symmetric_adaptor"></a>Symmetric Adaptor</h2>
+<h4>Description</h4>
+<p>The templated class <code>symmetric_adaptor&lt;M, F&gt;</code>
+is a symmetric matrix adaptor for other matrices.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/symmetric.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    symmetric_adaptor&lt;matrix&lt;double&gt;, lower&gt; sal (m);
+    for (unsigned i = 0; i &lt; sal.size1 (); ++ i)
+        for (unsigned j = 0; j &lt;= i; ++ j)
+            sal (i, j) = 3 * i + j;
+    std::cout &lt;&lt; sal &lt;&lt; std::endl;
+    symmetric_adaptor&lt;matrix&lt;double&gt;, upper&gt; sau (m);
+    for (unsigned i = 0; i &lt; sau.size1 (); ++ i)
+        for (unsigned j = i; j &lt; sau.size2 (); ++ j)
+            sau (i, j) = 3 * i + j;
+    std::cout &lt;&lt; sau &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header symmetric.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>M</code></td>
+<td>The type of the adapted matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>Functor describing the type of the symmetric adaptor. <a href=
+"#symmetric_adaptor_1">[1]</a></td>
+<td><code>lower</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;symmetric_adaptor&lt;M, F&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>symmetric_adaptor ()</code></td>
+<td>Constructs a <code>symmetric_adaptor</code> that holds zero
+rows of zero elements.</td>
+</tr>
+<tr>
+<td><code>symmetric_adaptor (matrix_type &amp;data)</code></td>
+<td>Constructs a <code>symmetric_adaptor</code> of a matrix.</td>
+</tr>
+<tr>
+<td><code>symmetric_adaptor (const symmetric_adaptor
+&amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_adaptor (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns a <code>const</code> reference of the <code>j</code>
+-th element in the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>symmetric_adaptor &amp;operator = (const
+symmetric_adaptor &amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>symmetric_adaptor &amp;assign_temporary
+(symmetric_adaptor &amp;m)</code></td>
+<td>Assigns a temporary. May change the symmetric adaptor
+<code>m</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_adaptor &amp;operator = (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_adaptor &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the symmetric adaptor. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_adaptor &amp;operator += (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the symmetric adaptor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_adaptor &amp;plus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a matrix expression to the symmetric adaptor. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_adaptor &amp;operator -= (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the symmetric adaptor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+symmetric_adaptor &amp;minus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a matrix expression from the symmetric adaptor. Left
+and right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+symmetric_adaptor &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the symmetric
+adaptor with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+symmetric_adaptor &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the symmetric adaptor
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (symmetric_adaptor &amp;m)</code></td>
+<td>Swaps the contents of the symmetric adaptors.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>symmetric_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>symmetric_adaptor</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="symmetric_adaptor_1">[1]</a>
+Supported parameters for the type of the symmetric adaptor are
+<code>lower</code> and <code>upper</code>.</p>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/triangular.html b/doc/triangular.html
new file mode 100644
index 0000000..865e191
--- /dev/null
+++ b/doc/triangular.html
@@ -0,0 +1,602 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Triangular Matrix</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Triangular Matrix</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="triangular_matrix"></a>Triangular Matrix</h2>
+<h4>Description</h4>
+<p>The templated class <code>triangular_matrix&lt;T, F1, F2,
+A&gt;</code> is the base container adaptor for triangular matrices.
+For a <em>(n x n</em> )-dimensional lower triangular matrix and
+<em>0 &lt;= i &lt; n</em>,<em>0 &lt;= j &lt; n</em> holds
+<em>t</em><sub><em>i, j</em></sub> <em>= 0</em> , if <em>i &gt;
+j</em>. If furthermore holds t<sub><em>i, i</em></sub><em>= 1</em>
+the matrix is called unit lower triangular. For a <em>(n x n</em>
+)-dimensional lower triangular matrix and <em>0 &lt;= i &lt;
+n</em>,<em>0 &lt;= j &lt; n</em> holds <em>t</em><sub><em>i,
+j</em></sub> <em>= 0</em> , if <em>i &lt; j</em>. If furthermore
+holds t<sub><em>i, i</em></sub><em>= 1</em> the matrix is called
+unit lower triangular. The storage of triangular matrices is
+packed.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/triangular.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    triangular_matrix&lt;double, lower&gt; ml (3, 3);
+    for (unsigned i = 0; i &lt; ml.size1 (); ++ i)
+        for (unsigned j = 0; j &lt;= i; ++ j)
+            ml (i, j) = 3 * i + j;
+    std::cout &lt;&lt; ml &lt;&lt; std::endl;
+    triangular_matrix&lt;double, upper&gt; mu (3, 3);
+    for (unsigned i = 0; i &lt; mu.size1 (); ++ i)
+        for (unsigned j = i; j &lt; mu.size2 (); ++ j)
+            mu (i, j) = 3 * i + j;
+    std::cout &lt;&lt; mu &lt;&lt; std::endl;
+}
+</pre>
+<p>Please read the <a href="samples/ex_triangular.cpp">full triangular example</a> for more details.</p>
+
+<h4>Definition</h4>
+<p>Defined in the header triangular.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F1</code></td>
+<td>Functor describing the type of the triangular matrix. <a href=
+"#triangular_matrix_1">[1]</a></td>
+<td><code>lower</code></td>
+</tr>
+<tr>
+<td><code>F2</code></td>
+<td>Functor describing the storage organization. <a href=
+"#triangular_matrix_2">[2]</a></td>
+<td><code>row_major</code></td>
+</tr>
+<tr>
+<td><code>A</code></td>
+<td>The type of the adapted array. <a href=
+"#triangular_matrix_3">[3]</a></td>
+<td><code>unbounded_array&lt;T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#matrix">Matrix</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#matrix">Matrix</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_container&lt;triangular_matrix&lt;T, F1, F2, A&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>triangular_matrix ()</code></td>
+<td>Allocates an uninitialized <code>triangular_matrix</code> that
+holds zero rows of zero elements.</td>
+</tr>
+<tr>
+<td><code>triangular_matrix (size_type size1, size_type
+size2)</code></td>
+<td>Allocates an uninitialized <code>triangular_matrix</code> that
+holds <code>size1</code> rows of <code>size2</code> elements.</td>
+</tr>
+<tr>
+<td><code>triangular_matrix (const triangular_matrix
+&amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_matrix (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size1, size_type size2, bool
+preserve = true)</code></td>
+<td>Reallocates a <code>triangular_matrix</code> to hold
+<code>size1</code> rows of <code>size2</code> elements. The
+existing elements of the <code>triangular_matrix</code> are
+preseved when specified.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns a <code>const</code> reference of the <code>j</code>
+-th element in the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>triangular_matrix &amp;operator = (const
+triangular_matrix &amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>triangular_matrix &amp;assign_temporary
+(triangular_matrix &amp;m)</code></td>
+<td>Assigns a temporary. May change the triangular matrix
+<code>m</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_matrix &amp;operator = (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_matrix &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the triangular matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_matrix &amp;operator += (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the triangular matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_matrix &amp;plus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a matrix expression to the triangular matrix. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_matrix &amp;operator -= (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the triangular matrix.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_matrix &amp;minus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a matrix expression from the triangular matrix. Left
+and right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+triangular_matrix &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the triangular
+matrix with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+triangular_matrix &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the triangular matrix
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (triangular_matrix &amp;m)</code></td>
+<td>Swaps the contents of the triangular matrices.</td>
+</tr>
+<tr>
+<td><code>void insert (size_type i, size_type j, const_reference
+t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>j</code>-th
+element of the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void erase (size_type i, size_type j)</code></td>
+<td>Erases the value at the <code>j</code>-th elemenst of the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the matrix.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>triangular_matrix</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>triangular_matrix</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="triangular_matrix_1">[1]</a>
+Supported parameters for the type of the triangular matrix are
+<code>lower</code> , <code>unit_lower</code>, <code>upper</code>
+and <code>unit_upper</code> .</p>
+<p><a name="triangular_matrix_2">[2]</a>
+Supported parameters for the storage organization are
+<code>row_major</code> and <code>column_major</code>.</p>
+<p><a name="triangular_matrix_3">[3]</a>
+Supported parameters for the adapted array are
+<code>unbounded_array&lt;T&gt;</code> ,
+<code>bounded_array&lt;T&gt;</code> and
+<code>std::vector&lt;T&gt;</code> .</p>
+<h2><a name="triangular_adaptor"></a>Triangular Adaptor</h2>
+<h4>Description</h4>
+<p>The templated class <code>triangular_adaptor&lt;M, F&gt;</code>
+is a triangular matrix adaptor for other matrices.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/triangular.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    matrix&lt;double&gt; m (3, 3);
+    triangular_adaptor&lt;matrix&lt;double&gt;, lower&gt; tal (m);
+    for (unsigned i = 0; i &lt; tal.size1 (); ++ i)
+        for (unsigned j = 0; j &lt;= i; ++ j)
+            tal (i, j) = 3 * i + j;
+    std::cout &lt;&lt; tal &lt;&lt; std::endl;
+    triangular_adaptor&lt;matrix&lt;double&gt;, upper&gt; tau (m);
+    for (unsigned i = 0; i &lt; tau.size1 (); ++ i)
+        for (unsigned j = i; j &lt; tau.size2 (); ++ j)
+            tau (i, j) = 3 * i + j;
+    std::cout &lt;&lt; tau &lt;&lt; std::endl;
+}
+</pre>
+<p>Please read the <a href="samples/ex_triangular.cpp">full triangular example</a> for more details.</p>
+
+<h4>Definition</h4>
+<p>Defined in the header triangular.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>M</code></td>
+<td>The type of the adapted matrix.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>Functor describing the type of the triangular adaptor. <a href=
+"#triangular_adaptor_1">[1]</a></td>
+<td><code>lower</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;triangular_adaptor&lt;M, F&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>triangular_adaptor (matrix_type &amp;data)</code></td>
+<td>Constructs a <code>triangular_adaptor</code> of a matrix.</td>
+</tr>
+<tr>
+<td><code>triangular_adaptor (const triangular_adaptor
+&amp;m)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_adaptor (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns a <code>const</code> reference of the <code>j</code>
+-th element in the <code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i, size_type
+j)</code></td>
+<td>Returns a reference of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>triangular_adaptor &amp;operator = (const
+triangular_adaptor &amp;m)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>triangular_adaptor &amp;assign_temporary
+(triangular_adaptor &amp;m)</code></td>
+<td>Assigns a temporary. May change the triangular adaptor
+<code>m</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_adaptor &amp;operator = (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_adaptor &amp;assign (const matrix_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a matrix expression to the triangular adaptor. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_adaptor &amp;operator += (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the matrix expression to
+the triangular adaptor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_adaptor &amp;plus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a matrix expression to the triangular adaptor. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_adaptor &amp;operator -= (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the matrix expression
+from the triangular adaptor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+triangular_adaptor &amp;minus_assign (const
+matrix_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a matrix expression from the triangular adaptor. Left
+and right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+triangular_adaptor &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the triangular
+adaptor with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+triangular_adaptor &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the triangular adaptor
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (triangular_adaptor &amp;m)</code></td>
+<td>Swaps the contents of the triangular adaptors.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 begin1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the beginning of
+the <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator1 end1 ()</code></td>
+<td>Returns a <code>iterator1</code> pointing to the end of the
+<code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 begin2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the beginning of
+the <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>iterator2 end2 ()</code></td>
+<td>Returns a <code>iterator2</code> pointing to the end of the
+<code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rbegin1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the
+beginning of the reversed <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator1 rend1 ()</code></td>
+<td>Returns a <code>reverse_iterator1</code> pointing to the end of
+the reversed <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rbegin2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the
+beginning of the reversed <code>triangular_adaptor</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator2 rend2 ()</code></td>
+<td>Returns a <code>reverse_iterator2</code> pointing to the end of
+the reversed <code>triangular_adaptor</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="triangular_adaptor_1">[1]</a>
+Supported parameters for the type of the triangular adaptor are
+<code>lower</code> , <code>unit_lower</code>, <code>upper</code>
+and <code>unit_upper</code> .</p>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/types_overview.html b/doc/types_overview.html
new file mode 100644
index 0000000..b68a7ce
--- /dev/null
+++ b/doc/types_overview.html
@@ -0,0 +1,580 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta name="GENERATOR" content="Quanta Plus" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Types Overview</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Overview of Matrix- and Vector-Types </h1>
+<div class="toc" id="toc"></div>
+
+<dl>
+<dt>Contents:</dt>
+<dd><a href="#vectors">Vectors</a></dd>
+<dd><a href="#vector_proxies">Vector Proxies</a></dd>
+<dd><a href="#matrices">Matrices</a></dd>
+<dd><a href="#matrix_proxies">Matrix Proxies</a></dd>
+<dd><a href="#storage_layout">Special Storage Layouts</a></dd>
+</dl>
+
+
+<h2>Notation</h2>
+
+<table style="border: none;" summary="notation">
+<tr><td><code>T</code></td> 
+<td>is the data type. For general linear algebra operations this will be a real type e.g. <code>double</code>, ...</td></tr>
+<tr><td><code>F</code></td> 
+<td>is the orientation type (functor), either
+<code>row_major</code> or <code>column_major</code></td></tr>
+<tr><td><code>A, IA, TA</code></td> <td>is an array storage type, e.g. <code>std::vector,
+bounded_array, unbounded_array, ...</code></td></tr>
+<tr><td><code>TRI</code></td> 
+<td>is a triangular functor: <code>lower,
+unit_lower, strict_lower, upper, unit_upper,
+strict_upper</code></td></tr>
+<tr><td><code>M, N</code></td> 
+<td>are unsigned integer sizes 
+(<code>std::size_t</code>)</td></tr>
+<tr><td><code>IB</code></td> 
+<td>is an index base
+(<code>std::size_t</code>)</td></tr>
+<tr><td><code>VEC</code></td> 
+<td>is any vector type</td></tr>
+<tr><td><code>MAT</code> </td>
+<td>is any matrix type</td></tr>
+<tr><td><code>[...]</code></td> 
+<td>denote optional arguments - for more details
+look at the section "storage layout".</td></tr>
+</table>
+
+<h2><a id="vectors">Vectors</a></h2>
+<table border="1" summary="vector types">
+<thead>
+<tr>
+<th width="30%">Definition</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code>vector&lt;T [, A]&gt;<br />&nbsp;&nbsp; v(size);</code></td>
+<td>a dense vector of values of type <code>T</code> of variable
+size. A storage type <code>A</code> can be specified
+which defaults to <code>unbounded_array</code>.
+Elements are constructed by <code>A</code>, which need not initialise their value.</td>
+
+</tr>
+<tr>
+<td><code>bounded_vector&lt;T, N&gt;<br />&nbsp;&nbsp; v;</code></td>
+<td>a dense vector of values of type <code>T</code> of variable size but with maximum
+<code>N</code>. The default constructor creates <code>v</code>
+with size <code>N</code>.
+Elements are constructed by the storage type <code>bounded_array</code>, which need not initialise their value.</td>
+</tr>
+<tr>
+<td><code>c_vector&lt;T, M&gt;<br />&nbsp;&nbsp; v(size);</code></td>
+<td>a dense vector of values of type <code>T</code> with the given size.
+The data is stored as an ordinary C++ array <code>T
+data_[M]</code></td>
+</tr>
+<tr>
+<td><code>zero_vector&lt;T&gt;<br />&nbsp;&nbsp; v(size);</code></td>
+<td>the zero vector of type <code>T</code> with the given
+size.</td>
+</tr>
+<tr>
+<td><code>unit_vector&lt;T&gt;<br />&nbsp;&nbsp; v(size,&nbsp;index);</code></td>
+<td>the unit vector of type <code>T</code> with the given size. The
+vector is zero other then a single specified element.
+<br/><code>index</code> should be less than <code>size</code>.</td>
+</tr>
+<tr>
+<td><code>mapped_vector&lt;T [, S]&gt;<br />&nbsp;&nbsp; v(size);</code></td>
+<td>a sparse vector of values of type <code>T</code> of variable
+size. The sparse storage type <code>S</code> can be <code>std::map&lt;size_t,
+T&gt;</code> or <code>map_array&lt;size_t, T&gt;</code>.</td>
+</tr>
+<tr>
+<td><code>compressed_vector&lt;T [,IB, IA, TA]&gt;<br />&nbsp;&nbsp; v(size);</code></td>
+<td>a sparse vector of values of type <code>T</code> of variable
+size. The non zero values are stored as two seperate arrays - an
+index array and a value array. The index array is always sorted and
+there is at most one entry for each index.</td>
+</tr>
+<tr>
+<td><code>coordinate_vector&lt;T [,IB, IA, TA]&gt;<br />&nbsp;&nbsp; v(size);</code></td>
+<td>a sparse vector of values of type <code>T</code> of variable
+size. The non zero values are stored as two seperate arrays - an
+index array and a value array. The arrays may be out of order with
+multiple entries for each vector element. If there are multiple
+values for the same index the sum of these values is the real
+value.</td>
+</tr>
+</tbody>
+</table>
+<p><em>Note:</em> the default types are defined in
+<code>boost/numeric/ublas/fwd.hpp</code>.</p>
+
+<h2><a id="vector_proxies">Vector Proxies</a></h2>
+
+<table border="1" summary="vector proxies">
+<thead>
+<tr>
+<th width="30%">Definition</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code>vector_range&lt;VEC&gt;<br />&nbsp;&nbsp; vr(v, range);</code></td>
+<td>a vector referencing a continuous subvector of elements of
+vector <code>v</code> containing all elements specified by
+<code>range</code>.</td>
+</tr>
+<tr>
+<td><code>vector_slice&lt;VEC&gt;<br />&nbsp;&nbsp; vs(v, slice);</code></td>
+<td>a vector referencing a non continuous subvector of elements of
+vector <code>v</code> containing all elements specified by
+<code>slice</code>.</td>
+</tr>
+<tr>
+<td><code>matrix_row&lt;MAT&gt;<br />&nbsp;&nbsp; vr(m, index);</code></td>
+<td>a vector referencing the <code>index</code>-th row of matrix
+<code>m</code></td>
+</tr>
+<tr>
+<td><code>matrix_column&lt;MAT&gt;<br />&nbsp;&nbsp; vc(m, index);</code></td>
+<td>a vector referencing the <code>index</code>-th column of matrix
+<code>m</code></td>
+</tr>
+</tbody>
+</table>
+
+<h2><a id="matrices">Matrices</a></h2>
+
+<table border="1" summary="matrix types">
+<thead>
+<tr>
+<th width="30%">Definition</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code>matrix&lt;T [, F, A]&gt;<br />&nbsp;&nbsp; m(size1, size2);</code></td>
+<td>a dense matrix of values of type <code>T</code> of variable
+size.  A storage type <code>A</code> can be specified
+which defaults to <code>unbounded_array</code>.
+The orientation functor <code>F</code> defaults to
+<code>row_major</code>.
+Elements are constructed by <code>A</code>, which need not initialise their value.</td>
+</tr>
+<tr>
+<td><code>bounded_matrix&lt;T, M, N [, F]&gt;<br />&nbsp;&nbsp; m;</code></td>
+<td>a dense matrix of type <code>T</code> with variable size with maximum <code>M</code>-by-<code>N</code>. The orientation functor <code>F</code>
+defaults to <code>row_major</code>. The default constructor creates
+<code>m</code> with size <code>M</code>-by-<code>N</code>.
+Elements are constructed by the storage type <code>bounded_array</code>, which need not initialise their value.</td>
+</tr>
+<tr>
+<td><code>c_matrix&lt;T, M, N&gt;<br />&nbsp;&nbsp; m(size1, size2);</code></td>
+<td>a dense matrix of values of type <code>T</code> with the given size.
+The data is stored as an ordinary C++ array <code>T
+data_[N][M]</code></td>
+</tr>
+<tr>
+<td><code>vector_of_vector&lt;T [, F, A]&gt;<br />&nbsp;&nbsp; m(size1,
+size2);</code></td>
+<td>a dense matrix of values of type <code>T</code> with the given size.
+The data is stored as a vector of vectors. The orientation
+<code>F</code> defaults to <code>row_major</code>. The storage
+type <code>S</code> defaults to
+<code>unbounded_array&lt;unbounded_array&lt;T&gt;&nbsp;&gt;</code></td>
+</tr>
+<tr>
+<td><code>zero_matrix&lt;T&gt;<br />&nbsp;&nbsp; m(size1, size2);</code></td>
+<td>a zero matrix of type <code>T</code> with the given size.</td>
+</tr>
+<tr>
+<td><code>identity_matrix&lt;T&gt;<br />&nbsp;&nbsp; m(size1, size2);</code></td>
+<td>an identity matrix of type <code>T</code> with the given size.
+The values are <code>v(i,j) = (i==j)?T(1):T()</code>.</td>
+</tr>
+<tr>
+<td><code>scalar_matrix&lt;T&gt;<br />&nbsp;&nbsp; m(size1, size2,
+value);</code></td>
+<td>a matrix of type <code>T</code> with the given size that has the
+value <code>value</code> everywhere.</td>
+</tr>
+<tr>
+<td><code>triangular_matrix&lt;T [, TRI, F, A]&gt;<br />&nbsp;&nbsp;
+m(size);</code></td>
+<td>a triangular matrix of values of type <code>T</code> of
+variable size. Only the nonzero elements are stored in the given
+order <code>F</code>. ("triangular packed storage") The triangular
+type <code>F</code> defaults to <code>lower</code>, the orientation
+type <code>F</code> defaults to <code>row_major</code>.</td>
+</tr>
+<tr>
+<td><code>banded_matrix&lt;T [, F, A]&gt;<br />&nbsp;&nbsp; m(size1, size2, n_lower,
+n_upper);</code></td>
+<td>a banded matrix of values of type <code>T</code> of variable
+size with <code>n_lower</code> sub diagonals and
+<code>n_upper</code> super diagonals. Only the nonzero elements are
+stored in the given order <code>F</code>. ("packed storage")</td>
+</tr>
+<tr>
+<td><code>symmetric_matrix&lt;T [, TRI, F, A]&gt;<br />&nbsp;&nbsp;
+m(size);</code></td>
+<td>a symmetric matrix of values of type <code>T</code> of
+variable size. Only the given triangular matrix is stored in the
+given order <code>F</code>.</td>
+</tr>
+<tr>
+<td><code>hermitian_matrix&lt;T [, TRI, F, A]&gt;<br />&nbsp;&nbsp;
+m(size);</code></td>
+<td>a hermitian matrix of values of type <code>T</code> of
+variable size. Only the given triangular matrix is stored using
+the order <code>F</code>.</td>
+</tr>
+<tr>
+<td><code>mapped_matrix&lt;T, [F, S]&gt;<br />&nbsp;&nbsp; m(size1, size2 [,
+non_zeros]);</code></td>
+<td>a sparse matrix of values of type <code>T</code> of variable
+size. The sparse storage type <code>S</code> can be either <code>std::map&lt;size_t,
+std::map&lt;size_t, T&gt;&nbsp;&gt;</code> or
+<code>map_array&lt;size_t, map_array&lt;size_t,
+T&gt;&nbsp;&gt;</code>.</td>
+</tr>
+<tr>
+<td><code>sparse_vector_of_sparse_vector&lt;T, [F, C]&gt;<br />&nbsp;&nbsp; m(size1,
+size2 [, non_zeros]);</code></td>
+<td>a sparse matrix of values of type <code>T</code> of variable
+size.</td>
+</tr>
+<tr>
+<td><code>compressed_matrix&lt;T, [F, IB, IA, TA]&gt;<br />&nbsp;&nbsp; m(size1,
+size2 [, non_zeros]);</code></td>
+<td>a sparse matrix of values of type <code>T</code> of variable
+size. The values are stored in compressed row/column storage.</td>
+</tr>
+<tr>
+<td><code>coordinate_matrix&lt;T, [F, IB, IA, TA]&gt;<br />&nbsp;&nbsp; m(size1,
+size2 [, non_zeros]);</code></td>
+<td>a sparse matrix of values of type <code>T</code> of variable
+size. The values are stored in 3 parallel array as triples (i, j,
+value). More than one value for each pair of indices is possible,
+the real value is the sum of all.</td>
+</tr>
+<tr>
+<td><code>generalized_vector_of_vector&lt;T, F, A&gt;<br />&nbsp;&nbsp; m(size1,
+size2 [, non_zeros]);</code></td>
+<td>a sparse matrix of values of type <code>T</code> of variable
+size. The values are stored as a vector of sparse vectors, e.g.
+<code>generalized_vector_of_vector&lt;double, row_major,
+unbounded_array&lt;coordinate_vector&lt;double&gt;&nbsp;&gt;&nbsp;&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<p><em>Note:</em> the default types are defined in
+<code>boost/numeric/ublas/fwd.hpp</code>.</p>
+
+<h2><a id="matrix_proxies">Matrix Proxies</a></h2>
+
+<table border="1" summary="matrix proxies">
+<thead>
+<tr>
+<th width="30%">Definition</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code>triangular_adaptor&lt;MAT, TRI&gt;<br />&nbsp;&nbsp; ta(m);</code></td>
+<td>a triangular matrix referencing a selection of elements of the
+matrix <code>m</code>.</td>
+</tr>
+<tr>
+<td><code>symmetric_adaptor&lt;MAT, TRI&gt;<br />&nbsp;&nbsp; sa(m);</code></td>
+<td>a symmetric matrix referencing a selection of elements of the
+matrix <code>m</code>.</td>
+</tr>
+<tr>
+<td><code>hermitian_adaptor&lt;MAT, TRI&gt;<br />&nbsp;&nbsp; ha(m);</code></td>
+<td>a hermitian matrix referencing a selection of elements of the
+matrix <code>m</code>.</td>
+</tr>
+<tr>
+<td><code>banded_adaptor&lt;MAT&gt;<br />&nbsp;&nbsp; ba(m, n_lower,
+n_upper);</code></td>
+<td>a banded matrix referencing a selection of elements of the
+matrix <code>m</code>.</td>
+</tr>
+<tr>
+<td><code>matrix_range&lt;MAT, TRI&gt;<br />&nbsp;&nbsp; mr(m, range1,
+range2);</code></td>
+<td>a matrix referencing a submatrix of elements in the matrix
+<code>m</code>.</td>
+</tr>
+<tr>
+<td><code>matrix_slice&lt;MAT, TRI&gt;<br />&nbsp;&nbsp; ms(m, slice1,
+slice2);</code></td>
+<td>a matrix referencing a non continues submatrix of elements in
+the matrix <code>m</code>.</td>
+</tr>
+</tbody>
+</table>
+
+
+
+<h2><a id="storage_layout">Special Storage Layouts</a></h2>
+
+
+<p>The library supports conventional dense, packed and basic sparse
+vector and matrix storage layouts. The description of the most
+common constructions of vectors and matrices comes next.</p>
+
+<table border="1" summary="storage layouts">
+<tbody>
+<tr>
+<th width="30%">Construction</th>
+<th>Comment</th>
+</tr>
+<tr>
+<td><code>vector&lt;T,<br />
+&nbsp;std::vector&lt;T&gt; &gt;<br />
+&nbsp;&nbsp;v (size)</code></td>
+<td>a dense vector, storage is provided by a standard
+vector.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>vector&lt;T,<br />
+&nbsp;unbounded_array&lt;T&gt; &gt;<br />
+&nbsp;&nbsp;v (size)</code></td>
+<td>a dense vector, storage is provided by a heap-based
+array.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>vector&lt;T,<br />
+&nbsp;bounded_array&lt;T, N&gt; &gt;<br />
+&nbsp;&nbsp;v (size)</code></td>
+<td>a dense vector, storage is provided by a stack-based
+array.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>mapped_vector&lt;T,<br />
+&nbsp;std::map&lt;std::size_t, T&gt; &gt;<br />
+&nbsp;&nbsp;v (size, non_zeros)</code></td>
+<td>a sparse vector, storage is provided by a standard
+map.</td>
+</tr>
+<tr>
+<td><code>mapped_vector&lt;T,<br />
+&nbsp;map_array&lt;std::size_t, T&gt; &gt;<br />
+&nbsp;&nbsp;v (size, non_zeros)</code></td>
+<td>a sparse vector, storage is provided by a map
+array.</td>
+</tr>
+<tr>
+<td><code>matrix&lt;T,<br />
+&nbsp;row_major,<br />
+&nbsp;std::vector&lt;T&gt; &gt;<br />
+&nbsp;&nbsp;m (size1, size2)</code></td>
+<td>a dense matrix, orientation is row major, storage is
+provided by a standard vector.</td>
+</tr>
+<tr>
+<td><code>matrix&lt;T,<br />
+&nbsp;column_major,<br />
+&nbsp;std::vector&lt;T&gt; &gt;<br />
+&nbsp;&nbsp;m (size1, size2)</code></td>
+<td>a dense matrix, orientation is column major, storage
+is provided by a standard vector.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>matrix&lt;T,<br />
+&nbsp;row_major,<br />
+&nbsp;unbounded_array&lt;T&gt; &gt;<br />
+&nbsp;&nbsp;m (size1, size2)</code></td>
+<td>a dense matrix, orientation is row major, storage is
+provided by a heap-based array.</td>
+</tr>
+<tr>
+<td><code>matrix&lt;T,<br />
+&nbsp;column_major,<br />
+&nbsp;unbounded_array&lt;T&gt; &gt;<br />
+&nbsp;&nbsp;m (size1, size2)</code></td>
+<td>a dense matrix, orientation is column major, storage
+is provided by a heap-based array.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>matrix&lt;T,<br />
+&nbsp;row_major,<br />
+&nbsp;bounded_array&lt;T, N1 * N2&gt; &gt;<br />
+&nbsp;&nbsp;m (size1, size2)</code></td>
+<td>a dense matrix, orientation is row major, storage is
+provided by a stack-based array.</td>
+</tr>
+<tr>
+<td><code>matrix&lt;T,<br />
+&nbsp;column_major,<br />
+&nbsp;bounded_array&lt;T, N1 * N2&gt; &gt;<br />
+&nbsp;&nbsp;m (size1, size2)</code></td>
+<td>a dense matrix, orientation is column major, storage
+is provided by a stack-based array.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>triangular_matrix&lt;T,<br />
+&nbsp;row_major, F, A&gt;<br />
+&nbsp;&nbsp;m (size)</code></td>
+<td>a packed triangular matrix, orientation is row
+major.</td>
+</tr>
+<tr>
+<td><code>triangular_matrix&lt;T,<br />
+&nbsp;column_major, F, A&gt;<br />
+&nbsp;&nbsp;m (size)</code></td>
+<td>a packed triangular matrix, orientation is column
+major.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>banded_matrix&lt;T,<br />
+&nbsp;row_major, A&gt;<br />
+&nbsp;&nbsp;m (size1, size2, lower, upper)</code></td>
+<td>a packed banded matrix, orientation is row
+major.</td>
+</tr>
+<tr>
+<td><code>banded_matrix&lt;T,<br />
+&nbsp;column_major, A&gt;<br />
+&nbsp;&nbsp;m (size1, size2, lower, upper)</code></td>
+<td>a packed banded matrix, orientation is column
+major.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>symmetric_matrix&lt;T,<br />
+&nbsp;row_major, F, A&gt;<br />
+&nbsp;&nbsp;m (size)</code></td>
+<td>a packed symmetric matrix, orientation is row
+major.</td>
+</tr>
+<tr>
+<td><code>symmetric_matrix&lt;T,<br />
+&nbsp;column_major, F, A&gt;<br />
+&nbsp;&nbsp;m (size)</code></td>
+<td>a packed symmetric matrix, orientation is column
+major.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>hermitian_matrix&lt;T,<br />
+&nbsp;row_major, F, A&gt;<br />
+&nbsp;&nbsp;m (size)</code></td>
+<td>a packed hermitian matrix, orientation is row
+major.</td>
+</tr>
+<tr>
+<td><code>hermitian_matrix&lt;T,<br />
+&nbsp;column_major, F, A&gt;<br />
+&nbsp;&nbsp;m (size)</code></td>
+<td>a packed hermitian matrix, orientation is column
+major.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>mapped_matrix&lt;T,<br />
+&nbsp;row_major,<br />
+&nbsp;std::map&lt;std::size_t, T&gt; &gt;<br />
+&nbsp;&nbsp;m (size1, size2, non_zeros)</code></td>
+<td>a sparse matrix, orientation is row major, storage
+is provided by a standard map.</td>
+</tr>
+<tr>
+<td><code>mapped_matrix&lt;T,<br />
+&nbsp;column_major,<br />
+&nbsp;std::map&lt;std::size_t, T&gt; &gt;<br />
+&nbsp;&nbsp;m (size1, size2, non_zeros)</code></td>
+<td>a sparse matrix, orientation is column major,
+storage is provided by a standard map.</td>
+</tr>
+<tr>
+<td><code>mapped_matrix&lt;T,<br />
+&nbsp;row_major,<br />
+&nbsp;map_array&lt;std::size_t, T&gt; &gt;<br />
+&nbsp;&nbsp;m (size1, size2, non_zeros)</code></td>
+<td>a sparse matrix, orientation is row major, storage
+is provided by a map array.</td>
+</tr>
+<tr>
+<td><code>mapped_matrix&lt;T,<br />
+&nbsp;column_major,<br />
+&nbsp;map_array&lt;std::size_t, T&gt; &gt;<br />
+&nbsp;&nbsp;m (size1, size2, non_zeros)</code></td>
+<td>a sparse matrix, orientation is column major,
+storage is provided by a map array.</td>
+</tr>
+<tr>
+<td><code>compressed_matrix&lt;T,<br />
+&nbsp;row_major&gt;<br />
+&nbsp;&nbsp;m (size1, size2, non_zeros)</code></td>
+<td>a compressed matrix, orientation is row major.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>compressed_matrix&lt;T,<br />
+&nbsp;column_major&gt;<br />
+&nbsp;&nbsp;m (size1, size2, non_zeros)</code></td>
+<td>a compressed matrix, orientation is column
+major.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>coordinate_matrix&lt;T,<br />
+&nbsp;row_major&gt;<br />
+&nbsp;&nbsp;m (size1, size2, non_zeros)</code></td>
+<td>a coordinate matrix, orientation is row major.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+<tr>
+<td><code>coordinate_matrix&lt;T,<br />
+&nbsp;column_major&gt;<br />
+&nbsp;&nbsp;m (size1, size2, non_zeros)</code></td>
+<td>a coordinate matrix, orientation is column
+major.<br />
+The storage layout usually is BLAS compliant.</td>
+</tr>
+</tbody>
+</table>
+
+<hr />
+<p>Copyright (&copy;) 2000-2004 Joerg Walter, Mathias Koch, Gunter
+Winkler, Michael Stevens<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/ublas.css b/doc/ublas.css
new file mode 100644
index 0000000..1531be7
--- /dev/null
+++ b/doc/ublas.css
@@ -0,0 +1,59 @@
+/*
+ *  Copyright 2000-2009 Michael Stevens, Mathias Koch, 
+ *  Joerg Walter, Gunter Winkler.
+ *
+ *  Use, modification and distribution are subject to the
+ *  Boost Software License, Version 1.0.
+ *  (See accompanying file LICENSE_1_0.txt
+ *  or copy at http://www.boost.org/LICENSE_1_0.txt).
+ */
+table {
+	border-width: medium;
+	background-color: #F8F8F8;
+	margin: 1em;
+}
+
+td {
+	padding-left: 0.5em;
+	padding-right: 0.5em;
+}
+
+th {
+	text-align: left;
+}
+
+pre.screen {
+	border: 1px solid #DCDCDC;
+	display: block;
+	font-size: 9pt;
+	margin: 1pc 4% 0;
+	padding: 0.5pc;
+}
+
+p.credit {
+	font-style: italic;
+}
+
+@media print {
+	div.toc { display: none; }
+}
+
+div.toc {
+	margin: 10px;
+	padding: 3px;
+}
+
+div#toc ul {
+	list-style: none;
+	margin: 1px;
+	padding-left: 1em;
+	margin-bottom: 0.25em;
+}
+
+div#toc ul li ul {
+	margin-bottom: 0.25em;
+}
+
+div#toc ul li ul li ul {
+	margin-bottom: 0.25em;
+}
\ No newline at end of file
diff --git a/doc/unbounded_array.html b/doc/unbounded_array.html
new file mode 100644
index 0000000..3be0730
--- /dev/null
+++ b/doc/unbounded_array.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Unbounded array</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Unbounded Array Storage</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="unbounded_array"></a>Unbounded Array</h2>
+<h4>Description</h4>
+<p>The templated class <code>unbounded_array&lt;T, ALLOC&gt;</code> implements a unbounded storage array using an allocator. 
+The unbounded array is similar to a <code>std::vector</code> in that in can grow in size beyond any fixed bound. 
+However <code>unbounded_array</code> is aimed at optimal performance. Therefore <code>unbounded_array</code> does not model a 
+<code>Sequence</code> like <code>std::vector</code> does.
+<p>When resized <code>unbounded_array</code> will reallocate it's storage even if the new size requirement is smaller. It is therefore inefficient to resize a <code>unbounded_array</code></p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/storage.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    unbounded_array&lt;double&gt; a (3);
+    for (unsigned i = 0; i &lt; a.size (); ++ i) {
+        a [i] = i;
+        std::cout &lt;&lt; a [i] &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header storage.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the array.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>ALLOC</code></td>
+<td>An STL Allocator</td>
+<td>std::allocator</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="storage_concept.html">Storage</a></p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of Storage.</p>
+<h4>Public base classes</h4>
+<p>None.</p>
+<h4>Members</h4>
+<ul>
+<li>The description does not describe what the member actually does, this can be looked up
+in the corresponding concept documentation, but instead contains a remark on the implementation of the
+member inside this model of the concept.</li>
+<li>Typography:
+<ul>
+<li>Members that are not part of the implemented concepts are <font color="blue">in blue</font>.</li>
+</ul>
+</li>
+</ul>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Where defined</th>
+<th>Description</th>
+</tr>
+<tr><td><code>value_type</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td></tr>
+<tr><td><code>pointer</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>value_type*</code></td></tr>
+<tr><td><code>const_pointer</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>const value_type*</code></td></tr>
+<tr><td><code>reference</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>value_type&amp;</code></td></tr>
+<tr><td><code>const_reference</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>const value_type&amp;</code></td></tr>
+<tr><td><code>size_type</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>Alloc::size_type</code></td></tr>
+<tr><td><code>difference_type</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>Alloc::difference_type</code></td></tr>
+<tr><td><code>iterator</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>pointer</code></td></tr>
+<tr><td><code>const_iterator</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>const_pointer</code></td></tr>
+<tr><td><code>revere_iterator</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>std::reverse_iterator&lt;iterator&gt;</code></td></tr>
+<tr><td><code>const_revere_iterator</code></td><td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td><td>Defined as <code>std::reverse_iterator&lt;const_iterator&gt;</code></td></tr>
+<tr><td><font color="blue">allocator_type</font></td><td></td><td>Defined as ALLOC</td></tr>
+<tr>
+<td><code><em>explicit</em> unbounded_array (<em>ALLOC &amp;a = ALLOC()</em>)</code></td>
+<td><a href="storage_concept.html">Storage</a></td>
+<td>Creates an <code>unbounded_array</code> that holds zero elements, using a specified allocator.</td> 
+</tr>
+<tr>
+<td><code><em>explicit</em> unbounded_array (size_type size<em>, ALLOC &amp;a = ALLOC()</em>)</code></td>
+<td><a href="storage_concept.html">Storage</a></td>
+<td>Creates a uninitialized <code>unbounded_array</code> that holds <code>size</code> elements, using a specified allocator. All the elements are default constructed.</td>
+</tr>
+<tr>
+<td><code>unbounded_array (size_type size, const T&amp; init<em>, ALLOC&amp; a = ALLOC()</em>)</code></td>
+<td><a href="storage_concept.html">Storage</a></td>
+<td>Creates an initialized <code>unbounded_array</code> that holds <code>size</code> elements, using a specified allocator. All the elements are constructed from the <code>init</code> value.</td>
+</tr>
+<tr>
+<td><code>unbounded_array (const unbounded_array &amp;a)</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>~unbounded_array ()</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Deallocates the <code>unbounded_array</code> itself.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type n)</code></td>
+<td><a href="storage_concept.html">Storage</a></td>
+<td>Reallocates an <code>unbounded_array</code> to hold <code>n</code> elements. Values are uninitialised.</td>
+</tr>
+<tr>
+<td><code>void resize(size_type n, const T&amp; t)</code></td>
+<td><a href="storage_concept.html">Storage</a></td>
+<td>Reallocates an <code>unbounded_array</code> to hold <code>n</code> elements. Values are copies of <code>t</code> 
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns the size of the <code>unbounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i) const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a <code>const</code> reference of the <code>i</code> -th element.</td>
+</tr>
+<tr>
+<td><code>reference operator [] (size_type i)</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>unbounded_array &amp;operator = (const unbounded_array &amp;a)</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><font color="blue"><code>unbounded_array &amp;assign_temporary (unbounded_array &amp;a)</code></font></td>
+<td></td>
+<td>Assigns a temporary. May change the array <code>a</code>.</td>
+</tr>
+<tr>
+<td><code>void swap (unbounded_array &amp;a)</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Swaps the contents of the arrays.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>unbounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>unbounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>unbounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td><a href="http://www.sgi.com/tech/stl/Container.html">Container</a></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>unbounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">Reversible Container</a></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the beginning of the reversed <code>unbounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">Reversible Container</a></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the end of the reversed <code>unbounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td><a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">Reversible Container</a></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the beginning of the reversed <code>unbounded_array</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td><a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">Reversible Container</a></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of the reversed <code>unbounded_array</code>.</td>
+</tr>
+</tbody>
+</table>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/vector.html b/doc/vector.html
new file mode 100644
index 0000000..2f9569d
--- /dev/null
+++ b/doc/vector.html
@@ -0,0 +1,755 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Vector</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Vector</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="vector"></a>Vector</h2>
+<h4>Description</h4>
+<p>The templated class <code>vector&lt;T, A&gt;</code> is the base
+container adaptor for dense vectors. For a <em>n</em>-dimensional
+vector and <em>0 &lt;= i &lt; n</em> every element
+<em>v</em><sub><em>i</em></sub> is mapped to the <em>i-</em>th
+element of the container.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;double&gt; v (3);
+    for (unsigned i = 0; i &lt; v.size (); ++ i)
+        v (i) = i;
+    std::cout &lt;&lt; v &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header vector.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the vector.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>A</code></td>
+<td>The type of the <a href="storage_concept.html">Storage</a> array. <a href="#vector_1">[1]</a></td>
+<td><code>unbounded_array&lt;T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#vector">Vector</a>,
+<a href="http://www.sgi.com/tech/stl/RandomAccessContainer.html">RandomAccessContainer</a>
+</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#vector">Vector</a>
+and <a href="http://www.sgi.com/tech/stl/RandomAccessContainer.html">RandomAccessContainer</a>.</p>
+<h4>Public base classes</h4>
+<p><code>vector_container&lt;vector&lt;T, A&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Where defined</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>value_type</code>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>reference</code>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>const_reference</code>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>size_type</code>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>difference_type</code>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>const_iterator</code>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>iterator</code>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator</code>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>reverse_iterator</code>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>array_type</code>
+<td><a href="container_concept.html#vector">Vector</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>vector ()</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Allocates an uninitialized <code>vector</code> that holds zero
+elements.</td>
+</tr>
+<tr>
+<td><code>vector (size_type size)</code></td>
+<td><a href="container_concept.html#vector">Vector</a></td>
+<td>Allocates an uninitialized <code>vector</code> that holds
+<code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>vector (const vector &amp;v)</code></td>
+<td></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector (const vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, bool preserve =
+true)</code></td>
+<td><a href="container_concept.html#vector">Vector</a></td>
+<td>Reallocates a <code>vector</code> to hold <code>size</code>
+elements. The existing elements of the <code>vector</code> are
+preseved when specified.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns the size of the <code>vector</code>.</td>
+</tr>
+<tr>
+<td><code>size_type max_size () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/RandomAccessContainer.html">RandomAccessContainer</a></td>
+<td>Returns the upper bound on the size of the <code>vector</code>.</td>
+</tr>
+<tr>
+<td><code>bool empty () const</code></td>
+<td><a href="http://www.sgi.com/tech/stl/RandomAccessContainer.html">RandomAccessContainer</a></td>
+<td>Equivilent to <code>size () == 0</code>.</td>
+</tr>
+<tr>
+<td><code>const array_type&amp; data () const</code></td>
+<td><a href="container_concept.html#vector">Vector</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>array_type&amp; data ()</code></td>
+<td><a href="container_concept.html#vector">Vector</a></td>
+<td></td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns a <code>const</code> reference of the <code>i</code>
+-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i) const</code></td>
+<td><a href="container_concept.html#vector">Vector</a></td>
+<td>Returns a <code>const</code> reference of the <code>i</code>
+-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator [] (size_type i)</code></td>
+<td><a href="container_concept.html#vector">Vector</a></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>vector &amp;operator = (const vector &amp;v)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>vector &amp;assign_temporary (vector &amp;v)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Assigns a temporary. May change the vector <code>v</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector &amp;operator = (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector &amp;assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Assigns a vector expression to the vector. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector &amp;operator += (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>A computed assignment operator. Adds the vector expression to
+the vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector &amp;plus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Adds a vector expression to the vector. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector &amp;operator -= (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>A computed assignment operator. Subtracts the vector expression
+from the vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector &amp;minus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Subtracts a vector expression from the vector. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+vector &amp;operator *= (const AT &amp;at)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>A computed assignment operator. Multiplies the vector with a
+scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+vector &amp;operator /= (const AT &amp;at)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>A computed assignment operator. Divides the vector through a
+scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (vector &amp;v)</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Swaps the contents of the vectors.</td>
+</tr>
+<tr>
+<td><code>void insert_element (size_type i, const_reference t)</code></td>
+<td><a href="container_concept.html#vector">Vector</a></td>
+<td>Inserts the value <code>t</code> at the <code>i</code>-th
+element.</td>
+</tr>
+<tr>
+<td><code>void erase_element (size_type i)</code></td>
+<td><a href="container_concept.html#vector">Vector</a></td>
+<td>Erases the value at the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td><a href="container_concept.html#vector">Vector</a></td>
+<td>Clears the vector.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>vector</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>vector</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>vector</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>vector</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td><a href="expression_concept.html#vector_expression">VectorExpression</a></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>vector</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="vector_1">[1]</a> Common parameters
+for the Storage array are <code>unbounded_array&lt;T&gt;</code> ,
+<code>bounded_array&lt;T&gt;</code> and
+<code>std::vector&lt;T&gt;</code> .</p>
+<h2><a name="unit_vector"></a>Unit Vector</h2>
+<h4>Description</h4>
+<p>The templated class <code>unit_vector&lt;T, ALLOC&gt;</code> represents
+canonical unit vectors. For the <em>k</em>-th
+<em>n</em>-dimensional canonical unit vector and <em>0 &lt;= i &lt;
+n</em> holds <em>u</em><sup><em>k</em></sup><sub><em>i</em></sub>
+<em>= 0</em>, if <em>i &lt;&gt; k</em>, and
+<em>u</em><sup><em>k</em></sup><sub><em>i</em></sub> <em>=
+1</em>.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    for (int i = 0; i &lt; 3; ++ i) {
+        unit_vector&lt;double&gt; v (3, i);
+        std::cout &lt;&lt; v &lt;&lt; std::endl;
+    }
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header vector.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the vector.</td>
+<td><code>int</code></td>
+</tr>
+<tr>
+<td><code>ALLOC</code></td>
+<td>An STL Allocator for size_type and difference_type.</td>
+<td>std::allocator</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#vector">Vector</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of
+<a href="container_concept.html#vector">Vector</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_container&lt;unit_vector&lt;T&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>unit_vector ()</code></td>
+<td>Constructs an <code>unit_vector</code> that holds zero
+elements.</td>
+</tr>
+<tr>
+<td><code>unit_vector (size_type size, size_type index)</code></td>
+<td>Constructs the <code>index</code>-th <code>unit_vector</code>
+that holds <code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>unit_vector (const unit_vector &amp;v)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, bool preserve =
+true)</code></td>
+<td>Resizes a <code>unit_vector</code> to hold <code>size</code>
+elements. Therefore the existing elements of the
+<code>unit_vector</code> are always preseved.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the <code>unit_vector</code>.</td>
+</tr>
+<tr>
+<td><code>size_type index () const</code></td>
+<td>Returns the index of the <code>unit_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>unit_vector &amp;operator = (const unit_vector
+&amp;v)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>unit_vector &amp;assign_temporary (unit_vector
+&amp;v)</code></td>
+<td>Assigns a temporary. May change the unit vector <code>v</code>
+.</td>
+</tr>
+<tr>
+<td><code>void swap (unit_vector &amp;v)</code></td>
+<td>Swaps the contents of the unit vectors.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>unit_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>unit_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>unit_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>unit_vector</code>.</td>
+</tr>
+</tbody>
+</table>
+<h2><a name="zero_vector"></a>Zero Vector</h2>
+<h4>Description</h4>
+<p>The templated class <code>zero_vector&lt;T, ALLOC&gt;</code> represents
+zero vectors. For a <em>n</em>-dimensional zero vector and <em>0
+&lt;= i &lt; n</em> holds <em>z</em><sub><em>i</em></sub> <em>=
+0</em>.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    zero_vector&lt;double&gt; v (3);
+    std::cout &lt;&lt; v &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header vector.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the vector.</td>
+<td><code>int</code></td>
+</tr>
+<tr>
+<td><code>ALLOC</code></td>
+<td>An STL Allocator for size_type and difference_type.</td>
+<td>std::allocator</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#vector">Vector</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of
+<a href="container_concept.html#vector">Vector</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_container&lt;zero_vector&lt;T&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>zero_vector ()</code></td>
+<td>Constructs a <code>zero_vector</code> that holds zero
+elements.</td>
+</tr>
+<tr>
+<td><code>zero_vector (size_type size)</code></td>
+<td>Constructs a <code>zero_vector</code> that holds
+<code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>zero_vector (const zero_vector &amp;v)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, bool preserve =
+true)</code></td>
+<td>Resizes a <code>zero_vector</code> to hold <code>size</code>
+elements. Therefore the existing elements of the
+<code>zero_vector</code> are always preseved.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the <code>zero_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>zero_vector &amp;operator = (const zero_vector
+&amp;v)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>zero_vector &amp;assign_temporary (zero_vector
+&amp;v)</code></td>
+<td>Assigns a temporary. May change the zero vector <code>v</code>
+.</td>
+</tr>
+<tr>
+<td><code>void swap (zero_vector &amp;v)</code></td>
+<td>Swaps the contents of the zero vectors.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>zero_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>zero_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>zero_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>zero_vector</code>.</td>
+</tr>
+</tbody>
+</table>
+<h2><a name="scalar_vector"></a>Scalar Vector</h2>
+<h4>Description</h4>
+<p>The templated class <code>scalar_vector&lt;T, ALLOC&gt;</code>
+represents scalar vectors. For a <em>n</em>-dimensional scalar
+vector and <em>0 &lt;= i &lt; n</em> holds
+<em>z</em><sub><em>i</em></sub> <em>= s</em>.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    scalar_vector&lt;double&gt; v (3);
+    std::cout &lt;&lt; v &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header vector.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the vector.</td>
+<td><code>int</code></td>
+</tr>
+<tr>
+<td><code>ALLOC</code></td>
+<td>An STL Allocator for size_type and difference_type.</td>
+<td>std::allocator</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#vector">Vector</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of
+<a href="container_concept.html#vector">Vector</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_container&lt;scalar_vector&lt;T&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>scalar_vector ()</code></td>
+<td>Constructs a <code>scalar_vector</code> that holds zero
+elements.</td>
+</tr>
+<tr>
+<td><code>scalar_vector (size_type size, const value_type
+&amp;value)</code></td>
+<td>Constructs a <code>scalar_vector</code> that holds
+<code>size</code> elements each of the specified value.</td>
+</tr>
+<tr>
+<td><code>scalar_vector (const scalar_vector &amp;v)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, bool preserve =
+true)</code></td>
+<td>Resizes a <code>scalar_vector</code> to hold <code>size</code>
+elements. Therefore the existing elements of the
+<code>scalar_vector</code> are always preseved.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the <code>scalar_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>scalar_vector &amp;operator = (const scalar_vector
+&amp;v)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>scalar_vector &amp;assign_temporary (scalar_vector
+&amp;v)</code></td>
+<td>Assigns a temporary. May change the scalar vector
+<code>v</code> .</td>
+</tr>
+<tr>
+<td><code>void swap (scalar_vector &amp;v)</code></td>
+<td>Swaps the contents of the scalar vectors.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>scalar_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>scalar_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>scalar_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>scalar_vector</code>.</td>
+</tr>
+</tbody>
+</table>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/vector_expression.html b/doc/vector_expression.html
new file mode 100644
index 0000000..7838007
--- /dev/null
+++ b/doc/vector_expression.html
@@ -0,0 +1,969 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Vector Expressions</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Vector Expressions</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="vector_expression"></a>Vector Expression</h2>
+<h4>Description</h4>
+<p>The templated class <code>vector_expression&lt;E&gt;</code>
+is required to be a public base of all classes which model the Vector Expression concept.</p>
+<h4>Definition</h4>
+<p>Defined in the header expression_types.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E</code></td>
+<td>The type of the vector expression.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p>None. <u>Not a Vector Expression</u>!
+</p>
+<h4>Type requirements</h4>
+<p>None.</p>
+<h4>Public base classes</h4>
+<p>None.</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>const expression_type &amp;operator () ()
+const</code></td>
+<td>Returns a <code>const</code> reference of the expression.</td>
+</tr>
+<tr>
+<td><code>expression_type &amp;operator () ()</code></td>
+<td>Returns a reference of the expression.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p>The <code>range</code>, <code>slice</code> and <code>project</code> functions have been removed. Use the free functions defined in <a href="vector_proxy.html">vector proxy</a> instead.</p>
+
+<h2><a name="vector_container"></a>Vector Container</h2>
+<h4>Description</h4>
+<p>The templated class <code>vector_container&lt;C&gt;</code>
+is required to be a public base of all classes which model the Vector concept.
+This includes the class <code>vector</code> itself.</p>
+<h4>Definition</h4>
+<p>Defined in the header expression_types.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>C</code></td>
+<td>The type of the vector container.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p>None. <u>Not a Vector Expression OR Vector</u>!
+</p>
+<h4>Type requirements</h4>
+<p>None.</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;C&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>const container_type &amp;operator () ()
+const</code></td>
+<td>Returns a <code>const</code> reference of the container.</td>
+</tr>
+<tr>
+<td><code>container_type &amp;operator () ()</code></td>
+<td>Returns a reference of the container.</td>
+</tr>
+</tbody>
+</table>
+
+<h2><a name="vector_references"></a>Vector References</h2>
+<h3>Reference</h3>
+<h4>Description</h4>
+<p>The templated class <code>vector_reference&lt;E&gt;</code>
+contains a reference to a vector expression.</p>
+<h4>Definition</h4>
+<p>Defined in the header vector_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E</code></td>
+<td>The type of the vector expression.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;vector_reference&lt;E&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>vector_reference (expression_type &amp;e)</code></td>
+<td>Constructs a reference of the expression.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size)</code></td>
+<td>Resizes the expression to hold at most <code>size</code>
+elements.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the expression.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the expression.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h2><a name="vector_operations"></a>Vector Operations</h2>
+<h3>Unary Operation Description</h3>
+<h4>Description</h4>
+<p>The templated class <code>vector_unary&lt;E, F&gt;</code>
+describes a unary vector operation.</p>
+<h4>Definition</h4>
+<p>Defined in the header vector_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E</code></td>
+<td>The type of the vector expression.</td>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>The type of the operation.</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;vector_unary&lt;E, F&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>vector_unary (const expression_type &amp;e)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the expression.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h3>Unary Operations</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class E, class F&gt;
+    struct vector_unary_traits {
+        typedef vector_unary&lt;typename E::const_closure_type, F&gt; expression_type;
+        typedef expression_type result_type;
+     };
+
+    // (- v) [i] = - v [i]
+    template&lt;class E&gt;
+     typename vector_unary_traits&lt;E, scalar_negate&lt;typename E::value_type&gt; &gt;::result_type
+    operator - (const vector_expression&lt;E&gt; &amp;e);
+
+    // (conj v) [i] = conj (v [i])
+    template&lt;class E&gt;
+     typename vector_unary_traits&lt;E, scalar_conj&lt;typename E::value_type&gt; &gt;::result_type
+    conj (const vector_expression&lt;E&gt; &amp;e);
+
+    // (real v) [i] = real (v [i])
+    template&lt;class E&gt;
+     typename vector_unary_traits&lt;E, scalar_real&lt;typename E::value_type&gt; &gt;::result_type
+    real (const vector_expression&lt;E&gt; &amp;e);
+
+    // (imag v) [i] = imag (v [i])
+    template&lt;class E&gt;
+     typename vector_unary_traits&lt;E, scalar_imag&lt;typename E::value_type&gt; &gt;::result_type
+    imag (const vector_expression&lt;E&gt; &amp;e);
+
+    // (trans v) [i] = v [i]
+    template&lt;class E&gt;
+     typename vector_unary_traits&lt;E, scalar_identity&lt;typename E::value_type&gt; &gt;::result_type
+    trans (const vector_expression&lt;E&gt; &amp;e);
+
+    // (herm v) [i] = conj (v [i])
+    template&lt;class E&gt;
+     typename vector_unary_traits&lt;E, scalar_conj&lt;typename E::value_type&gt; &gt;::result_type
+    herm (const vector_expression&lt;E&gt; &amp;e);</code>
+</pre>
+<h4>Description</h4>
+<p><code>operator -</code> computes the additive inverse of a
+vector expression. <code>conj</code> computes the complex conjugate
+of a vector expression. <code>real</code> and <code>imag</code>
+compute the real and imaginary parts of a vector expression.
+<code>trans</code> computes the transpose of a vector expression.
+<code>herm</code> computes the hermitian, i.e. the complex
+conjugate of the transpose of a vector expression.</p>
+<h4>Definition</h4>
+<p>Defined in the header vector_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E</code> is a model of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<p>None.</p>
+<h4>Complexity</h4>
+<p>Linear depending from the size of the vector expression.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;std::complex&lt;double&gt; &gt; v (3);
+    for (unsigned i = 0; i &lt; v.size (); ++ i)
+        v (i) = std::complex&lt;double&gt; (i, i);
+
+    std::cout &lt;&lt; - v &lt;&lt; std::endl;
+    std::cout &lt;&lt; conj (v) &lt;&lt; std::endl;
+    std::cout &lt;&lt; real (v) &lt;&lt; std::endl;
+    std::cout &lt;&lt; imag (v) &lt;&lt; std::endl;
+    std::cout &lt;&lt; trans (v) &lt;&lt; std::endl;
+    std::cout &lt;&lt; herm (v) &lt;&lt; std::endl;
+}
+</pre>
+<h3>Binary Operation Description</h3>
+<h4>Description</h4>
+<p>The templated class <code>vector_binary&lt;E1, E2, F&gt;</code>
+describes a binary vector operation.</p>
+<h4>Definition</h4>
+<p>Defined in the header vector_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E1</code></td>
+<td>The type of the first vector expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>E2</code></td>
+<td>The type of the second vector expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>The type of the operation.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;vector_binary&lt;E1, E2, F&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>vector_binary (const expression1_type &amp;e1, const
+expression2_type &amp;e2)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the expression.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h3>Binary Operations</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class E1, class E2, class F&gt;
+    struct vector_binary_traits {
+        typedef vector_binary&lt;typename E1::const_closure_type,
+                               typename E2::const_closure_type, F&gt; expression_type;
+        typedef expression_type result_type;
+     };
+
+    // (v1 + v2) [i] = v1 [i] + v2 [i]
+    template&lt;class E1, class E2&gt;
+    typename vector_binary_traits&lt;E1, E2, scalar_plus&lt;typename E1::value_type,
+                                                       typename E2::value_type&gt; &gt;::result_type
+    operator + (const vector_expression&lt;E1&gt; &amp;e1,
+                 const vector_expression&lt;E2&gt; &amp;e2);
+
+    // (v1 - v2) [i] = v1 [i] - v2 [i]
+    template&lt;class E1, class E2&gt;
+    typename vector_binary_traits&lt;E1, E2, scalar_minus&lt;typename E1::value_type,
+                                                        typename E2::value_type&gt; &gt;::result_type
+    operator - (const vector_expression&lt;E1&gt; &amp;e1,
+                 const vector_expression&lt;E2&gt; &amp;e2);</code>
+</pre>
+<h4>Description</h4>
+<p><code>operator +</code> computes the sum of two vector
+expressions. <code>operator -</code> computes the difference of two
+vector expressions.</p>
+<h4>Definition</h4>
+<p>Defined in the header vector_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E1</code> is a model of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</li>
+<li><code>E2</code> is a model of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<ul>
+<li><code>e1 ().size () == e2 ().size ()</code></li>
+</ul>
+<h4>Complexity</h4>
+<p>Linear depending from the size of the vector expressions.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;double&gt; v1 (3), v2 (3);
+    for (unsigned i = 0; i &lt; std::min (v1.size (), v2.size ()); ++ i)
+        v1 (i) = v2 (i) = i;
+
+    std::cout &lt;&lt; v1 + v2 &lt;&lt; std::endl;
+    std::cout &lt;&lt; v1 - v2 &lt;&lt; std::endl;
+}
+</pre>
+<h3>Binary Outer Operation Description</h3>
+<h4>Description</h4>
+<p>The templated class <code>vector_matrix_binary&lt;E1, E2,
+F&gt;</code> describes a binary outer vector operation.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E1</code></td>
+<td>The type of the first vector expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>E2</code></td>
+<td>The type of the second vector expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>The type of the operation.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#matrix_expression">Matrix Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#matrix_expression">Matrix Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>matrix_expression&lt;vector_matrix_binary&lt;E1, E2, F&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>vector_matrix_binary (const expression1_type &amp;e1,
+const expression2_type &amp;e2)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>size_type size1 () const</code></td>
+<td>Returns the number of rows.</td>
+</tr>
+<tr>
+<td><code>size_type size2 () const</code></td>
+<td>Returns the number of columns.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i, size_type j)
+const</code></td>
+<td>Returns the value of the <code>j</code>-th element in the
+<code>i</code>-th row.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 begin1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator1 end1 () const</code></td>
+<td>Returns a <code>const_iterator1</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 begin2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the
+beginning of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator2 end2 () const</code></td>
+<td>Returns a <code>const_iterator2</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rbegin1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator1 rend1 () const</code></td>
+<td>Returns a <code>const_reverse_iterator1</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rbegin2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator2 rend2 () const</code></td>
+<td>Returns a <code>const_reverse_iterator2</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h3>Binary Outer Operations</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class E1, class E2, class F&gt;
+    struct vector_matrix_binary_traits {
+        typedef vector_matrix_binary&lt;typename E1::const_closure_type,
+                                      typename E2::const_closure_type, F&gt; expression_type;
+        typedef expression_type result_type;
+     };
+
+    // (outer_prod (v1, v2)) [i] [j] = v1 [i] * v2 [j]
+    template&lt;class E1, class E2&gt;
+    typename vector_matrix_binary_traits&lt;E1, E2, scalar_multiplies&lt;typename E1::value_type, typename E2::value_type&gt; &gt;::result_type
+    outer_prod (const vector_expression&lt;E1&gt; &amp;e1,
+                 const vector_expression&lt;E2&gt; &amp;e2);</code>
+</pre>
+<h4>Description</h4>
+<p><code>outer_prod</code> computes the outer product of two vector
+expressions.</p>
+<h4>Definition</h4>
+<p>Defined in the header matrix_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E1</code> is a model of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</li>
+<li><code>E2</code> is a model of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<p>None.</p>
+<h4>Complexity</h4>
+<p>Quadratic depending from the size of the vector expressions.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/matrix.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;double&gt; v1 (3), v2 (3);
+    for (unsigned i = 0; i &lt; std::min (v1.size (), v2.size ()); ++ i)
+        v1 (i) = v2 (i) = i;
+
+    std::cout &lt;&lt; outer_prod (v1, v2) &lt;&lt; std::endl;
+}
+</pre>
+<h3>Scalar Vector Operation Description</h3>
+<h4>Description</h4>
+<p>The templated classes <code>vector_binary_scalar1&lt;E1, E2,
+F&gt;</code> and <code>vector_binary_scalar2&lt;E1, E2,
+F&gt;</code> describe binary operations between a scalar and a
+vector.</p>
+<h4>Definition</h4>
+<p>Defined in the header vector_expression.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>E1/E2</code></td>
+<td>The type of the scalar expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>E2/E1</code></td>
+<td>The type of the vector expression.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>F</code></td>
+<td>The type of the operation.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;vector_binary_scalar1&lt;E1, E2,
+F&gt; &gt;</code> and
+<code>vector_expression&lt;vector_binary_scalar2&lt;E1, E2, F&gt;
+&gt;</code> resp.</p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>vector_binary_scalar1 (const expression1_type &amp;e1,
+const expression2_type &amp;e2)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>vector_binary_scalar2 (const expression1_type &amp;e1,
+const expression2_type &amp;e2)</code></td>
+<td>Constructs a description of the expression.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the expression.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the expression.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed expression.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed expression.</td>
+</tr>
+</tbody>
+</table>
+<h3>Scalar Vector Operations</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class T1, class E2, class F&gt;
+    struct vector_binary_scalar1_traits {
+        typedef vector_binary_scalar1&lt;scalar_const_reference&lt;T1&gt;,
+                                      typename E2::const_closure_type, F&gt; expression_type;
+        typedef expression_type result_type;
+    };
+
+    // (t * v) [i] = t * v [i]
+    template&lt;class T1, class E2&gt;
+    typename vector_binary_scalar1_traits&lt;T1, E2, scalar_multiplies&lt;T1, typename E2::value_type&gt; &gt;::result_type
+    operator * (const T1 &amp;e1,
+                const vector_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class E1, class T2, class F&gt;
+    struct vector_binary_scalar2_traits {
+        typedef vector_binary_scalar2&lt;typename E1::const_closure_type,
+                                      scalar_const_reference&lt;T2&gt;, F&gt; expression_type;
+        typedef expression_type result_type;
+    };
+
+    // (v * t) [i] = v [i] * t
+    template&lt;class E1, class T2&gt;
+    typename vector_binary_scalar2_traits&lt;E1, T2, scalar_multiplies&lt;typename E1::value_type, T2&gt; &gt;::result_type
+    operator * (const vector_expression&lt;E1&gt; &amp;e1,
+                const T2 &amp;e2);
+
+    // (v / t) [i] = v [i] / t
+    template&lt;class E1, class T2&gt;
+    typename vector_binary_scalar2_traits&lt;E1, T2, scalar_divides&lt;typename E1::value_type, T2&gt; &gt;::result_type
+    operator / (const vector_expression&lt;E1&gt; &amp;e1,
+                const T2 &amp;e2);</code>
+</pre>
+<h4>Description</h4>
+<p><code>operator *</code> computes the product of a scalar and a
+vector expression. <code>operator /</code> multiplies the vector
+with the reciprocal of the scalar.</p>
+<h4>Definition</h4>
+<p>Defined in the header vector_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>T1/T2</code> is a model of <a href=
+"expression_concept.html#scalar_expression">Scalar Expression</a> .</li>
+<li><code>E2/E1</code> is a model of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<p>None.</p>
+<h4>Complexity</h4>
+<p>Linear depending from the size of the vector expression.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;double&gt; v (3);
+    for (unsigned i = 0; i &lt; v.size (); ++ i)
+        v (i) = i;
+
+    std::cout &lt;&lt; 2.0 * v &lt;&lt; std::endl;
+    std::cout &lt;&lt; v * 2.0 &lt;&lt; std::endl;
+}
+</pre>
+<h2><a name="vector_reductions"></a>Vector Reductions</h2>
+<h3>Unary Reductions</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class E, class F&gt;
+    struct vector_scalar_unary_traits {
+         typedef typename F::result_type result_type;
+    };
+
+    // sum v = sum (v [i])
+    template&lt;class E&gt;
+    typename vector_scalar_unary_traits&lt;E, vector_sum&lt;typename E::value_type&gt; &gt;::result_type
+    sum (const vector_expression&lt;E&gt; &amp;e);
+
+    // norm_1 v = sum (abs (v [i]))
+    template&lt;class E&gt;
+    typename vector_scalar_unary_traits&lt;E, vector_norm_1&lt;typename E::value_type&gt; &gt;::result_type
+    norm_1 (const vector_expression&lt;E&gt; &amp;e);
+
+    // norm_2 v = sqrt (sum (v [i] * v [i]))
+    template&lt;class E&gt;
+    typename vector_scalar_unary_traits&lt;E, vector_norm_2&lt;typename E::value_type&gt; &gt;::result_type
+    norm_2 (const vector_expression&lt;E&gt; &amp;e);
+
+    // norm_inf v = max (abs (v [i]))
+    template&lt;class E&gt;
+    typename vector_scalar_unary_traits&lt;E, vector_norm_inf&lt;typename E::value_type&gt; &gt;::result_type
+    norm_inf (const vector_expression&lt;E&gt; &amp;e);
+
+    // index_norm_inf v = min (i: abs (v [i]) == max (abs (v [i])))
+    template&lt;class E&gt;
+    typename vector_scalar_unary_traits&lt;E, vector_index_norm_inf&lt;typename E::value_type&gt; &gt;::result_type
+    index_norm_inf (const vector_expression&lt;E&gt; &amp;e);</code>
+</pre>
+<h4>Description</h4>
+<p><code>sum</code> computes the sum of the vector expression's
+elements. <code>norm_1</code>, <code>norm_2</code> and
+<code>norm_inf</code> compute the corresponding
+<em>||.||</em><sub><em>1</em></sub>,
+<em>||.||</em><sub><em>2</em></sub> and
+<em>||.||</em><sub><em>inf</em></sub> vector norms.
+<code>index_norm_1</code> computes the index of the vector
+expression's first element having maximal absolute value.</p>
+<h4>Definition</h4>
+<p>Defined in the header vector_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E</code> is a model of <a href=
+"#vector_expression">Vector Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<p>None.</p>
+<h4>Complexity</h4>
+<p>Linear depending from the size of the vector expression.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;double&gt; v (3);
+    for (unsigned i = 0; i &lt; v.size (); ++ i)
+        v (i) = i;
+
+    std::cout &lt;&lt; sum (v) &lt;&lt; std::endl;
+    std::cout &lt;&lt; norm_1 (v) &lt;&lt; std::endl;
+    std::cout &lt;&lt; norm_2 (v) &lt;&lt; std::endl;
+    std::cout &lt;&lt; norm_inf (v) &lt;&lt; std::endl;
+    std::cout &lt;&lt; index_norm_inf (v) &lt;&lt; std::endl;
+}
+</pre>
+<h3>Binary Reductions</h3>
+<h4>Prototypes</h4>
+<pre>
+<code>template&lt;class E1, class E2, class F&gt;
+    struct vector_scalar_binary_traits {
+        typedef typename F::result_type result_type;
+    };
+
+    // inner_prod (v1, v2) = sum (v1 [i] * v2 [i])
+    template&lt;class E1, class E2&gt;
+    typename vector_scalar_binary_traits&lt;E1, E2, vector_inner_prod&lt;typename E1::value_type,
+                                                                   typename E2::value_type,
+                                                                   typename promote_traits&lt;typename E1::value_type,
+                                                                                           typename E2::value_type&gt;::promote_type&gt; &gt;::result_type
+    inner_prod (const vector_expression&lt;E1&gt; &amp;e1,
+                const vector_expression&lt;E2&gt; &amp;e2);
+
+    template&lt;class E1, class E2&gt;
+    typename vector_scalar_binary_traits&lt;E1, E2, vector_inner_prod&lt;typename E1::value_type,
+                                                                   typename E2::value_type,
+                                                                   typename type_traits&lt;typename promote_traits&lt;typename E1::value_type,
+                                                                                                                typename E2::value_type&gt;::promote_type&gt;::precision_type&gt; &gt;::result_type
+    prec_inner_prod (const vector_expression&lt;E1&gt; &amp;e1,
+                     const vector_expression&lt;E2&gt; &amp;e2);</code>
+</pre>
+<h4>Description</h4>
+<p><code>inner_prod</code> computes the inner product of the vector
+expressions. <code>prec_inner_prod</code> computes the double
+precision inner product of the vector expressions<code>.</code></p>
+<h4>Definition</h4>
+<p>Defined in the header vector_expression.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>E1</code> is a model of <a href=
+"#vector_expression">Vector Expression</a> .</li>
+<li><code>E2</code> is a model of <a href=
+"#vector_expression">Vector Expression</a> .</li>
+</ul>
+<h4>Preconditions</h4>
+<ul>
+<li><code>e1 ().size () == e2 ().size ()</code></li>
+</ul>
+<h4>Complexity</h4>
+<p>Linear depending from the size of the vector expressions.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;double&gt; v1 (3), v2 (3);
+    for (unsigned i = 0; i &lt; std::min (v1.size (), v2.size ()); ++ i)
+        v1 (i) = v2 (i) = i;
+
+    std::cout &lt;&lt; inner_prod (v1, v2) &lt;&lt; std::endl;
+}
+</pre>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/vector_proxy.html b/doc/vector_proxy.html
new file mode 100644
index 0000000..a8a7376
--- /dev/null
+++ b/doc/vector_proxy.html
@@ -0,0 +1,527 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+<title>Vector Proxies</title>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Vector Proxies</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="vector_range"></a>Vector Range</h2>
+<h4>Description</h4>
+<p>The templated class <code>vector_range&lt;V&gt;</code> allows
+addressing a sub-range of a vector's element.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/vector_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;double&gt; v (3);
+    vector_range&lt;vector&lt;double&gt; &gt; vr (v, range (0, 3));
+    for (unsigned i = 0; i &lt; vr.size (); ++ i)
+        vr (i) = i;
+    std::cout &lt;&lt; vr &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header vector_proxy.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>V</code></td>
+<td>The type of vector referenced.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<p>If the specified range falls outside that of the index range of
+the vector, then the <code>vector_range</code> is not a well formed
+Vector Expression. That is, access to an element which is outside
+of index range of the vector is <i>undefined</i>.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;vector_range&lt;V&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>vector_range (vector_type &amp;data, const range
+&amp;r)</code></td>
+<td>Constructs a sub vector.</td>
+</tr>
+<tr>
+<td><code>size_type start () const</code></td>
+<td>Returns the start of the sub vector.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the sub vector.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator [] (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>vector_range &amp;operator = (const vector_range
+&amp;vr)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>vector_range &amp;assign_temporary (vector_range
+&amp;vr)</code></td>
+<td>Assigns a temporary. May change the vector range
+<code>vr</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_range &amp;operator = (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_range &amp;assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a vector expression to the sub vector. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_range &amp;operator += (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the vector expression to
+the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_range &amp;plus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a vector expression to the sub vector. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_range &amp;operator -= (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the vector expression
+from the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_range &amp;minus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a vector expression from the sub vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+vector_range &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the sub vector with
+a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+vector_range &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the sub vector through
+a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (vector_range &amp;vr)</code></td>
+<td>Swaps the contents of the sub vectors.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>vector_range</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>vector_range</code>.</td>
+</tr>
+</tbody>
+</table>
+<h3>Simple Projections</h3>
+<h4>Description</h4>
+<p>The free <code>subrange</code> functions support the construction
+of vector ranges.</p>
+<h4>Prototypes</h4>
+<pre><code>
+    template&lt;class V&gt;
+    vector_range&lt;V&gt; subrange (V &amp;data,
+       V::size_type start, V::size_type stop);
+    template&lt;class V&gt;
+    const vector_range&lt;const V&gt; subrange (const V &amp;data,
+       V::size_type start, V::size_type stop);
+</code></pre>
+<h3>Generic Projections</h3>
+<h4>Description</h4>
+<p>The free <code>project</code> functions support the construction
+of vector ranges. Existing <code>matrix_range</code>'s can be composed with a further range. The resulting range is computed using this existing range's <code>compose</code> function.</p>
+<h4>Prototypes</h4>
+<pre><code>
+    template&lt;class V&gt;
+    vector_range&lt;V&gt; project (V &amp;data, const range &amp;r);
+    template&lt;class V&gt;
+    const vector_range&lt;const V&gt; project (const V &amp;data, const range &amp;r);
+    template&lt;class V&gt;
+    vector_range&lt;V&gt; project (vector_range&lt;V&gt; &amp;data, const range &amp;r);
+    template&lt;class V&gt;
+    const vector_range&lt;V&gt; project (const vector_range&lt;V&gt; &amp;data, const range &amp;r);
+</code></pre>
+<h4>Definition</h4>
+<p>Defined in the header vector_proxy.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>V</code> is a model of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</li>
+</ul>
+<h4>Complexity</h4>
+<p>Linear depending from the size of the range.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/vector_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;double&gt; v (3);
+    for (int i = 0; i &lt; 3; ++ i)
+        project (v, range (0, 3)) (i) = i;
+    std::cout &lt;&lt; project (v, range (0, 3)) &lt;&lt; std::endl;
+}
+</pre>
+<h2><a name="vector_slice"></a>Vector Slice</h2>
+<h4>Description</h4>
+<p>The templated class <code>vector_slice&lt;V&gt;</code> allows
+addressing a slice of a vector.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/vector_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;double&gt; v (3);
+    vector_slice&lt;vector&lt;double&gt; &gt; vs (v, slice (0, 1, 3));
+    for (unsigned i = 0; i &lt; vs.size (); ++ i)
+        vs (i) = i;
+    std::cout &lt;&lt; vs &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header vector_proxy.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>V</code></td>
+<td>The type of vector referenced.</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="expression_concept.html#vector_expression">Vector Expression</a>
+.</p>
+<p>If the specified slice falls outside that of the index range of
+the vector, then the <code>vector_slice</code> is not a well formed
+Vector Expression. That is, access to an element which is outside
+of index range of the vector is <i>undefined</i>.</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_expression&lt;vector_slice&lt;V&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>vector_slice (vector_type &amp;data, const slice
+&amp;s)</code></td>
+<td>Constructs a sub vector.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the sub vector.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator [] (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>vector_slice &amp;operator = (const vector_slice
+&amp;vs)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>vector_slice &amp;assign_temporary (vector_slice
+&amp;vs)</code></td>
+<td>Assigns a temporary. May change the vector slice
+<code>vs</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_slice &amp;operator = (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_slice &amp;assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a vector expression to the sub vector. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_slice &amp;operator += (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the vector expression to
+the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_slice &amp;plus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a vector expression to the sub vector. Left and right hand
+side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_slice &amp;operator -= (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the vector expression
+from the sub vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+vector_slice &amp;minus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a vector expression from the sub vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+vector_slice &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the sub vector with
+a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+vector_slice &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the sub vector through
+a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (vector_slice &amp;vs)</code></td>
+<td>Swaps the contents of the sub vectors.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>vector_slice</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>vector_slice</code>.</td>
+</tr>
+</tbody>
+</table>
+<h3>Simple Projections</h3>
+<h4>Description</h4>
+<p>The free <code>subslice</code> functions support the construction
+of vector slices.</p>
+<h4>Prototypes</h4>
+<pre><code>
+    template&lt;class V&gt;
+    vector_slice&lt;V&gt; subslice (V &amp;data,
+       V::size_type start, V::difference_type stride, V::size_type size);
+    template&lt;class V&gt;
+    const vector_slice&lt;const V&gt; subslice (const V &amp;data,
+       V::size_type start, V::difference_type stride, V::size_type size);
+</code></pre>
+<h3>Generic Projections</h3>
+<h4>Description</h4>
+<p>The free <code>project</code> functions support the construction
+of vector slices. Existing <code>vector_slice</code>'s can be composed with a further range or slices. The resulting slice is computed using this existing slices's <code>compose</code> function.</p>
+<h4>Prototypes</h4>
+<pre><code>
+    template&lt;class V&gt;
+    vector_slice&lt;V&gt; project (V &amp;data, const slice &amp;s);
+    template&lt;class V&gt;
+    const vector_slice&lt;const V&gt; project (const V &amp;data, const slice &amp;s);
+    template&lt;class V&gt;
+    vector_slice&lt;V&gt; project (vector_slice&lt;V&gt; &amp;data, const range &amp;r);
+    template&lt;class V&gt;
+    const vector_slice&lt;V&gt; project (const vector_slice&lt;V&gt; &amp;data, const range &amp;r);
+    template&lt;class V&gt;
+    vector_slice&lt;V&gt; project (vector_slice&lt;V&gt; &amp;data, const slice &amp;s);
+    template&lt;class V&gt;
+    const vector_slice&lt;V&gt; project (const vector_slice&lt;V&gt; &amp;data, const slice &amp;s);
+</code></pre>
+<h4>Definition</h4>
+<p>Defined in the header vector_proxy.hpp.</p>
+<h4>Type requirements</h4>
+<ul>
+<li><code>V</code> is a model of <a href=
+"expression_concept.html#vector_expression">Vector Expression</a> .</li>
+</ul>
+<h4>Complexity</h4>
+<p>Linear depending from the size of the slice.</p>
+<h4>Examples</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector.hpp&gt;
+#include &lt;boost/numeric/ublas/vector_proxy.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    vector&lt;double&gt; v (3);
+    for (int i = 0; i &lt; 3; ++ i)
+        project (v, slice (0, 1, 3)) (i) = i;
+    std::cout &lt;&lt; project (v, slice (0, 1, 3)) &lt;&lt; std::endl;
+}
+</pre>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/doc/vector_sparse.html b/doc/vector_sparse.html
new file mode 100644
index 0000000..32279b0
--- /dev/null
+++ b/doc/vector_sparse.html
@@ -0,0 +1,800 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content=
+"HTML Tidy for Linux/x86 (vers 1st March 2004), see www.w3.org" />
+<meta http-equiv="Content-Type" content=
+"text/html; charset=us-ascii" />
+<link href="ublas.css" type="text/css" />
+<link rel="stylesheet" href="../../../../boost.css" type="text/css"/>
+<link rel="stylesheet" href="ublas.css" type="text/css" />
+<script type="text/javascript" src="js/jquery-1.3.2.min.js" async="async" ></script>
+<script type="text/javascript" src="js/jquery.toc-gw.js" async="async" ></script>
+</head>
+<body>
+<h1><img src="../../../../boost.png" align="middle" />Sparse Vector</h1>
+<div class="toc" id="toc"></div>
+<h2><a name="mapped_vector"></a>Mapped Vector</h2>
+<h4>Description</h4>
+<p>The templated class <code>mapped_vector&lt;T, A&gt;</code> is
+the base container adaptor for sparse vectors using element maps. For a
+<em>n</em>-dimensional sparse vector and <em>0 &lt;= i &lt; n</em>
+the non-zero elements <em>v</em><sub><em>i</em></sub> are mapped to
+consecutive elements of the associative container, i.e. for
+elements <em>k</em> =
+<em>v</em><sub><em>i</em></sub><sub><sub><em>1</em></sub></sub>and
+<em>k + 1 =
+v</em><sub><em>i</em></sub><sub><sub><em>2</em></sub></sub>of the
+container holds <em>i</em><sub><em>1</em></sub> <em>&lt;
+i</em><sub><em>2</em></sub>.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector_sparse.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    mapped_vector&lt;double&gt; v (3, 3);
+    for (unsigned i = 0; i &lt; v.size (); ++ i)
+        v (i) = i;
+    std::cout &lt;&lt; v &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header vector_sparse.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the mapped vector.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>A</code></td>
+<td>The type of the adapted array. <a href=
+"#mapped_vector_1">[1]</a></td>
+<td><code>map_std&lt;std::size_t, T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#vector">Vector</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#vector">Vector</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_container&lt;mapped_vector&lt;T, A&gt;
+&gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>mapped_vector ()</code></td>
+<td>Allocates a <code>mapped_vector</code> that holds zero
+elements.</td>
+</tr>
+<tr>
+<td><code>mapped_vector (size_type size, size_type
+non_zeros = 0)</code></td>
+<td>Allocates a <code>mapped_vector</code> that holds at most
+<code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>mapped_vector (const mapped_vector &amp;v)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_vector (size_type non_zeros, const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, bool
+preserve = true)</code></td>
+<td>Reallocates a <code>mapped_vector</code> to hold at most
+<code>size</code> elements. The existing elements of the
+<code>mapped_vector</code> are preseved when specified.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the <code>mapped_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator [] (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>mapped_vector &amp;operator = (const mapped_vector
+&amp;v)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>mapped_vector &amp;assign_temporary (mapped_vector
+&amp;v)</code></td>
+<td>Assigns a temporary. May change the mapped vector
+<code>v</code> .</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_vector &amp;operator = (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_vector &amp;assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a vector expression to the mapped vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_vector &amp;operator += (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Adds the vector expression to
+the mapped vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_vector &amp;plus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Adds a vector expression to the mapped vector. Left and right
+hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_vector &amp;operator -= (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the vector expression
+from the mapped vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+mapped_vector &amp;minus_assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Subtracts a vector expression from the mapped vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+mapped_vector &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the mapped vector
+with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+mapped_vector &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the mapped vector
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (mapped_vector &amp;v)</code></td>
+<td>Swaps the contents of the mapped vectors.</td>
+</tr>
+<tr>
+<td><code>true_reference insert_element (size_type i, const_reference t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>i</code>-th
+element. Duplicates elements are not allowed.</td>
+</tr>
+<tr>
+<td><code>void erase_element (size_type i)</code></td>
+<td>Erases the value at the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the mapped vector.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>mapped_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>mapped_vector</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>mapped_vector</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>mapped_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>mapped_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>mapped_vector</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>mapped_vector</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>mapped_vector</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="mapped_vector_1">[1]</a> Supported
+parameters for the adapted array are
+<code>map_array&lt;std::size_t, T&gt;</code> and
+<code>map_std&lt;std::size_t, T&gt;</code>. The latter is
+equivalent to <code>std::map&lt;std::size_t, T&gt;</code>.</p>
+<h2><a name="compressed_vector"></a>Compressed Vector</h2>
+<h4>Description</h4>
+<p>The templated class <code>compressed_vector&lt;T, IB, IA,
+TA&gt;</code> is the base container adaptor for compressed vectors.
+For a <em>n</em>-dimensional compressed vector and <em>0 &lt;= i
+&lt; n</em> the non-zero elements <em>v</em><sub><em>i</em></sub>
+are mapped to consecutive elements of the index and value
+container, i.e. for elements <em>k</em> =
+<em>v</em><sub><em>i</em></sub><sub><sub><em>1</em></sub></sub>and
+<em>k + 1 =
+v</em><sub><em>i</em></sub><sub><sub><em>2</em></sub></sub>of these
+containers holds <em>i</em><sub><em>1</em></sub> <em>&lt;
+i</em><sub><em>2</em></sub>.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector_sparse.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    compressed_vector&lt;double&gt; v (3, 3);
+    for (unsigned i = 0; i &lt; v.size (); ++ i)
+        v (i) = i;
+    std::cout &lt;&lt; v &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header vector_sparse.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the compressed vector.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>IB</code></td>
+<td>The index base of the compressed vector. <a href=
+"#compressed_vector_1">[1]</a></td>
+<td><code>0</code></td>
+</tr>
+<tr>
+<td><code>IA</code></td>
+<td>The type of the adapted array for indices. <a href=
+"#compressed_vector_2">[2]</a></td>
+<td><code>unbounded_array&lt;std::size_t&gt;</code></td>
+</tr>
+<tr>
+<td><code>TA</code></td>
+<td>The type of the adapted array for values. <a href=
+"#compressed_vector_2">[2]</a></td>
+<td><code>unbounded_array&lt;T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#vector">Vector</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#vector">Vector</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_container&lt;compressed_vector&lt;T, IB, IA,
+TA&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>compressed_vector ()</code></td>
+<td>Allocates a <code>compressed_vector</code> that holds zero
+elements.</td>
+</tr>
+<tr>
+<td><code>compressed_vector (size_type size, size_type
+non_zeros)</code></td>
+<td>Allocates a <code>compressed_vector</code> that holds at most
+<code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>compressed_vector (const compressed_vector
+&amp;v)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_vector (size_type non_zeros, const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, bool
+preserve = true)</code></td>
+<td>Reallocates a <code>compressed_vector</code> to hold at most
+<code>size</code> elements. The existing elements of the
+<code>compress_vector</code> are preseved when specified.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the <code>compressed_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator [] (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>compressed_vector &amp;operator = (const
+compressed_vector &amp;v)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>compressed_vector &amp;assign_temporary
+(compressed_vector &amp;v)</code></td>
+<td>Assigns a temporary. May change the compressed vector
+<code>v</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_vector &amp;operator = (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_vector &amp;assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a vector expression to the compressed vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_vector &amp;operator += (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the vector expression to
+the compressed vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_vector &amp;plus_assign (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a vector expression to the compressed vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_vector &amp;operator -= (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the vector expression
+from the compressed vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+compressed_vector &amp;minus_assign (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a vector expression from the compressed vector. Left
+and right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+compressed_vector &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the compressed
+vector with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+compressed_vector &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the compressed vector
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (compressed_vector &amp;v)</code></td>
+<td>Swaps the contents of the compressed vectors.</td>
+</tr>
+<tr>
+<td><code>true_reference insert_element (size_type i, const_reference t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>i</code>-th
+element. Duplicates elements are not allowed.</td>
+</tr>
+<tr>
+<td><code>void erase_element (size_type i)</code></td>
+<td>Erases the value at the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the compressed vector.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>compressed_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>compressed_vector</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>compressed_vector</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>compressed_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>compressed_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>compressed_vector</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>compressed_vector</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>compressed_vector</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="compressed_vector_1">[1]</a>
+Supported parameters for the index base are <code>0</code> and
+<code>1</code> at least.</p>
+<p><a name="compressed_vector_2">[2]</a>
+Supported parameters for the adapted array are
+<code>unbounded_array&lt;&gt;</code> ,
+<code>bounded_array&lt;&gt;</code> and
+<code>std::vector&lt;&gt;</code> .</p>
+<h2><a name="coordinate_vector"></a>Coordinate Vector</h2>
+<h4>Description</h4>
+<p>The templated class <code>coordinate_vector&lt;T, IB, IA,
+TA&gt;</code> is the base container adaptor for compressed vectors.
+For a <em>n</em>-dimensional sorted coordinate vector and <em>0
+&lt;= i &lt; n</em> the non-zero elements
+<em>v</em><sub><em>i</em></sub> are mapped to consecutive elements
+of the index and value container, i.e. for elements <em>k</em> =
+<em>v</em><sub><em>i</em></sub><sub><sub><em>1</em></sub></sub>and
+<em>k + 1 =
+v</em><sub><em>i</em></sub><sub><sub><em>2</em></sub></sub>of these
+containers holds <em>i</em><sub><em>1</em></sub> <em>&lt;
+i</em><sub><em>2</em></sub>.</p>
+<h4>Example</h4>
+<pre>
+#include &lt;boost/numeric/ublas/vector_sparse.hpp&gt;
+#include &lt;boost/numeric/ublas/io.hpp&gt;
+
+int main () {
+    using namespace boost::numeric::ublas;
+    coordinate_vector&lt;double&gt; v (3, 3);
+    for (unsigned i = 0; i &lt; v.size (); ++ i)
+        v (i) = i;
+    std::cout &lt;&lt; v &lt;&lt; std::endl;
+}
+</pre>
+<h4>Definition</h4>
+<p>Defined in the header vector_sparse.hpp.</p>
+<h4>Template parameters</h4>
+<table border="1" summary="parameters">
+<tbody>
+<tr>
+<th>Parameter</th>
+<th>Description</th>
+<th>Default</th>
+</tr>
+<tr>
+<td><code>T</code></td>
+<td>The type of object stored in the coordinate vector.</td>
+<td></td>
+</tr>
+<tr>
+<td><code>IB</code></td>
+<td>The index base of the coordinate vector. <a href=
+"#coordinate_vector_1">[1]</a></td>
+<td><code>0</code></td>
+</tr>
+<tr>
+<td><code>IA</code></td>
+<td>The type of the adapted array for indices. <a href=
+"#coordinate_vector_2">[2]</a></td>
+<td><code>unbounded_array&lt;std::size_t&gt;</code></td>
+</tr>
+<tr>
+<td><code>TA</code></td>
+<td>The type of the adapted array for values. <a href=
+"#coordinate_vector_2">[2]</a></td>
+<td><code>unbounded_array&lt;T&gt;</code></td>
+</tr>
+</tbody>
+</table>
+<h4>Model of</h4>
+<p><a href="container_concept.html#vector">Vector</a> .</p>
+<h4>Type requirements</h4>
+<p>None, except for those imposed by the requirements of <a href=
+"container_concept.html#vector">Vector</a> .</p>
+<h4>Public base classes</h4>
+<p><code>vector_container&lt;coordinate_vector&lt;T, IB, IA,
+TA&gt; &gt;</code></p>
+<h4>Members</h4>
+<table border="1" summary="members">
+<tbody>
+<tr>
+<th>Member</th>
+<th>Description</th>
+</tr>
+<tr>
+<td><code>coordinate_vector ()</code></td>
+<td>Allocates a <code>coordinate_vector</code> that holds zero
+elements.</td>
+</tr>
+<tr>
+<td><code>coordinate_vector (size_type size, size_type
+non_zeros)</code></td>
+<td>Allocates a <code>coordinate_vector</code> that holds at most
+<code>size</code> elements.</td>
+</tr>
+<tr>
+<td><code>coordinate_vector (const coordinate_vector
+&amp;v)</code></td>
+<td>The copy constructor.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_vector (size_type non_zeros, const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended copy constructor.</td>
+</tr>
+<tr>
+<td><code>void resize (size_type size, bool
+preserve = true)</code></td>
+<td>Reallocates a <code>coordinate_vector</code> to hold at most
+<code>size</code> elements. The existing elements of the
+<code>coordinate_vector</code> are preseved when specified.</td>
+</tr>
+<tr>
+<td><code>size_type size () const</code></td>
+<td>Returns the size of the <code>coordinate_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reference operator () (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator () (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>const_reference operator [] (size_type i)
+const</code></td>
+<td>Returns the value of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>reference operator [] (size_type i)</code></td>
+<td>Returns a reference of the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>coordinate_vector &amp;operator = (const
+coordinate_vector &amp;v)</code></td>
+<td>The assignment operator.</td>
+</tr>
+<tr>
+<td><code>coordinate_vector &amp;assign_temporary
+(coordinate_vector &amp;v)</code></td>
+<td>Assigns a temporary. May change the coordinate vector
+<code>v</code>.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_vector &amp;operator = (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>The extended assignment operator.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_vector &amp;assign (const vector_expression&lt;AE&gt;
+&amp;ae)</code></td>
+<td>Assigns a vector expression to the coordinate vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_vector &amp;operator += (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Adds the vector expression to
+the coordinate vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_vector &amp;plus_assign (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Adds a vector expression to the coordinate vector. Left and
+right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_vector &amp;operator -= (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>A computed assignment operator. Subtracts the vector expression
+from the coordinate vector.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AE&gt;<br />
+coordinate_vector &amp;minus_assign (const
+vector_expression&lt;AE&gt; &amp;ae)</code></td>
+<td>Subtracts a vector expression from the coordinate vector. Left
+and right hand side of the assignment should be independent.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+coordinate_vector &amp;operator *= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Multiplies the coordinate
+vector with a scalar.</td>
+</tr>
+<tr>
+<td><code>template&lt;class AT&gt;<br />
+coordinate_vector &amp;operator /= (const AT &amp;at)</code></td>
+<td>A computed assignment operator. Divides the coordinate vector
+through a scalar.</td>
+</tr>
+<tr>
+<td><code>void swap (coordinate_vector &amp;v)</code></td>
+<td>Swaps the contents of the coordinate vectors.</td>
+</tr>
+<tr>
+<td><code>true_reference insert_element (size_type i, const_reference t)</code></td>
+<td>Inserts the value <code>t</code> at the <code>i</code>-th
+element. Duplicates elements are not allowed.</td>
+</tr>
+<tr>
+<td><code>void append_element (size_type i, size_type j, const_reference t)</code></td>
+<td>Appends the value <code>t</code> at the <code>i</code>-th element.
+Duplicate elements can be appended to a <code>coordinate_vector</code>. They are merged into a single
+arithmetically summed element by the <code>sort</code> function.</td>
+</tr>
+<tr>
+<td><code>void erase_element (size_type i)</code></td>
+<td>Erases the value at the <code>i</code>-th element.</td>
+</tr>
+<tr>
+<td><code>void clear ()</code></td>
+<td>Clears the coordinate vector.</td>
+</tr>
+<tr>
+<td><code>const_iterator begin () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the beginning
+of the <code>coordinate_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_iterator end () const</code></td>
+<td>Returns a <code>const_iterator</code> pointing to the end of
+the <code>coordinate_vector</code>.</td>
+</tr>
+<tr>
+<td><code>iterator begin ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the beginning of
+the <code>coordinate_vector</code>.</td>
+</tr>
+<tr>
+<td><code>iterator end ()</code></td>
+<td>Returns a <code>iterator</code> pointing to the end of the
+<code>coordinate_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rbegin () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+beginning of the reversed <code>coordinate_vector</code>.</td>
+</tr>
+<tr>
+<td><code>const_reverse_iterator rend () const</code></td>
+<td>Returns a <code>const_reverse_iterator</code> pointing to the
+end of the reversed <code>coordinate_vector</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rbegin ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the
+beginning of the reversed <code>coordinate_vector</code>.</td>
+</tr>
+<tr>
+<td><code>reverse_iterator rend ()</code></td>
+<td>Returns a <code>reverse_iterator</code> pointing to the end of
+the reversed <code>coordinate_vector</code>.</td>
+</tr>
+</tbody>
+</table>
+<h4>Notes</h4>
+<p><a name="coordinate_vector_1">[1]</a>
+Supported parameters for the index base are <code>0</code> and
+<code>1</code> at least.</p>
+<p><a name="coordinate_vector_2">[2]</a>
+Supported parameters for the adapted array are
+<code>unbounded_array&lt;&gt;</code> ,
+<code>bounded_array&lt;&gt;</code> and
+<code>std::vector&lt;&gt;</code> .</p>
+<hr />
+<p>Copyright (&copy;) 2000-2002 Joerg Walter, Mathias Koch<br />
+   Use, modification and distribution are subject to the
+   Boost Software License, Version 1.0.
+   (See accompanying file LICENSE_1_0.txt
+   or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+      http://www.boost.org/LICENSE_1_0.txt
+   </a>).
+</p>
+<script type="text/javascript">
+(function($) {
+    $('#toc').toc();
+})(jQuery);
+</script>
+</body>
+</html>
diff --git a/include/boost/numeric/ublas/assignment.hpp b/include/boost/numeric/ublas/assignment.hpp
new file mode 100644
index 0000000..d2079e1
--- /dev/null
+++ b/include/boost/numeric/ublas/assignment.hpp
@@ -0,0 +1,1281 @@
+//
+//  Copyright (c) 2010 Athanasios Iliopoulos
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASSIGNMENT_HPP
+#define ASSIGNMENT_HPP
+#include <boost/numeric/ublas/vector_expression.hpp>
+#include <boost/numeric/ublas/matrix_expression.hpp>
+
+/*! \file assignment.hpp
+    \brief uBlas assignment operator <<=.
+*/
+
+namespace boost { namespace numeric { namespace ublas {
+
+/** \brief A CRTP and Barton-Nackman trick index manipulator wrapper class.
+ *
+ * This class is not meant to be used directly.
+ */
+template <class TV>
+class index_manipulator {
+public:
+    typedef TV type;
+    BOOST_UBLAS_INLINE
+    const type &operator () () const {
+        return *static_cast<const type *> (this);
+    }
+    BOOST_UBLAS_INLINE
+    type &operator () () {
+        return *static_cast<type *> (this);
+    }
+};
+
+/** \brief A move_to vector index manipulator.
+ *
+ * When member function \c manip is called the referenced
+ * index will be set to the manipulators' index.
+ *
+ * \sa move_to(T i)
+ */
+template <typename T>
+class vector_move_to_manip: public index_manipulator<vector_move_to_manip<T> > {
+public:
+    BOOST_UBLAS_INLINE
+    vector_move_to_manip(const T &k): i(k) { }
+
+    template <typename V>
+    BOOST_UBLAS_INLINE
+    void manip(V &k) const { k=i; }
+private:
+    T i;
+};
+
+/** \brief An object generator that returns a move_to vector index manipulator
+ *
+ * \param i The element number the manipulator will move to when \c manip member function is called
+ * \return A move_to vector manipulator
+ *
+ * Example usage:
+ * \code
+ * vector<double> a(6, 0);
+ * a <<= 1, 2, move_to(5), 3;
+ * \endcode
+ * will result in:
+ * \code
+ * 1 2 0 0 0 3
+ * \endcode
+ *
+ * \tparam T Size type
+ * \sa move_to()
+ */
+template <typename T>
+BOOST_UBLAS_INLINE vector_move_to_manip<T>  move_to(T i) {
+    return vector_move_to_manip<T>(i);
+}
+
+/** \brief A static move to vector manipulator.
+ *
+ * When member function \c manip is called the referenced
+ * index will be set to the manipulators' index
+ *
+ * \sa move_to(T i) and move_to()
+*/
+template <std::size_t I>
+class static_vector_move_to_manip: public index_manipulator<static_vector_move_to_manip<I> > {
+public:
+    template <typename V>
+    BOOST_UBLAS_INLINE
+    void manip(V &k) const { k=I; }
+};
+
+/** \brief An object generator that returns a static move_to vector index  manipulator.
+ *
+ * Typically faster than the dynamic version, but can be used only when the
+ * values are known at compile time.
+ *
+ * \return A static move_to vector manipulator
+ *
+ * Example usage:
+ * \code
+ * vector<double> a(6, 0);
+ * a <<= 1, 2, move_to<5>(), 3;
+ * \endcode
+ * will result in:
+ * \code
+ * 1 2 0 0 0 3
+ * \endcode
+ *
+ * \tparam I The number of elements the manipulator will traverse the index when \c manip function is called
+ */
+template <std::size_t I>
+BOOST_UBLAS_INLINE static_vector_move_to_manip<I>  move_to() {
+    return static_vector_move_to_manip<I>();
+}
+
+/** \brief A move vector index manipulator.
+ *
+ * When member function traverse is called the manipulators'
+ * index will be added to the referenced index.
+ *
+ * \see move(T i)
+ */
+template <typename T>
+class vector_move_manip: public index_manipulator<vector_move_manip<T> > {
+public:
+    BOOST_UBLAS_INLINE
+    vector_move_manip(const T &k): i(k) { }
+
+    template <typename V>
+    BOOST_UBLAS_INLINE void manip(V &k) const { k+=i; }
+private:
+    T i;
+};
+
+/**
+* \brief  An object generator that returns a move vector index manipulator
+*
+* \tparam T Size type
+* \param i The number of elements the manipulator will traverse the index when \c manip
+* member function is called. Negative values can be used.
+* \return A move vector manipulator
+*
+* Example usage:
+* \code
+* vector<double> a(6, 0);
+* a <<= 1, 2, move(3), 3;
+* \endcode
+* will result in:
+* \code
+* 1 2 0 0 0 3
+* \endcode
+*
+*/
+template <typename T>
+BOOST_UBLAS_INLINE vector_move_manip<T>  move(T i) {
+    return vector_move_manip<T>(i);
+}
+
+/**
+* \brief A static move vector manipulator
+*
+* When member function \c manip is called the manipulators
+* index will be added to the referenced index
+*
+* \sa move()
+*
+* \todo Doxygen has some problems with similar template functions. Correct that.
+*/
+template <std::ptrdiff_t I>
+class static_vector_move_manip: public index_manipulator<static_vector_move_manip<I> > {
+public:
+    template <typename V>
+    BOOST_UBLAS_INLINE void manip(V &k) const { k+=I; }
+};
+
+/**
+* \brief An object generator that returns a static move vector index manipulator.
+*
+* Typically faster than the dynamic version, but can be used only when the
+* values are known at compile time.
+* \tparam I The Number of elements the manipulator will traverse the index when \c manip
+* function is called.Negative values can be used.
+* \return A static move vector manipulator
+*
+* Example usage:
+* \code
+* vector<double> a(6, 0);
+* a <<= 1, 2, move<3>(), 3;
+* \endcode
+* will result in:
+* \code
+* 1 2 0 0 0 3
+* \endcode
+*
+* \todo Doxygen has some problems with similar template functions. Correct that.
+*/
+template <std::ptrdiff_t I>
+static_vector_move_manip<I>  move() {
+    return static_vector_move_manip<I>();
+}
+
+/**
+* \brief A move_to matrix manipulator
+*
+* When member function \c manip is called the referenced
+* index will be set to the manipulators' index
+*
+* \sa move_to(T i, T j)
+*
+* \todo Doxygen has some problems with similar template functions. Correct that.
+*/
+template <typename T>
+class matrix_move_to_manip: public index_manipulator<matrix_move_to_manip<T> > {
+public:
+    BOOST_UBLAS_INLINE
+    matrix_move_to_manip(T k, T l): i(k), j(l) { }
+
+    template <typename V1, typename V2>
+    BOOST_UBLAS_INLINE
+    void manip(V1 &k, V2 &l) const {
+        k=i;
+        l=j;
+    }
+private:
+    T i, j;
+};
+
+/**
+* \brief  An object generator that returns a "move_to" matrix index manipulator
+*
+* \tparam size type
+* \param i The row number the manipulator will move to when \c manip
+* member function is called
+* \param j The column number the manipulator will move to when \c manip
+* member function is called
+* \return A move matrix manipulator
+*
+* Example usage:
+* \code:
+* matrix<double> A(3, 3, 0);
+* A <<= 1, 2, move_to(A.size1()-1, A.size1()-1), 3;
+* \endcode
+* will result in:
+* \code
+* 1 2 0
+* 0 0 0
+* 0 0 3
+* \endcode
+* \sa move_to(T i, T j) and static_matrix_move_to_manip
+*
+* \todo Doxygen has some problems with similar template functions. Correct that.
+*/
+template <typename T>
+BOOST_UBLAS_INLINE matrix_move_to_manip<T>  move_to(T i, T j) {
+    return matrix_move_to_manip<T>(i, j);
+}
+
+
+/**
+* \brief A static move_to matrix manipulator
+* When member function traverse is called the referenced
+* index will be set to the manipulators' index
+*
+* \sa move_to()
+*
+* \todo Doxygen has some problems with similar template functions. Correct that.
+*/
+template <std::size_t I,std::size_t J>
+class static_matrix_move_to_manip: public index_manipulator<static_matrix_move_to_manip<I, J> > {
+public:
+    template <typename V, typename K>
+    BOOST_UBLAS_INLINE
+    void manip(V &k, K &l) const {
+        k=I;
+        l=J;
+    }
+};
+
+/**
+* \brief  An object generator that returns a static move_to matrix index manipulator.
+*
+* Typically faster than the dynamic version, but can be used only when the
+* values are known at compile time.
+* \tparam I The row number the manipulator will set the matrix assigner index to.
+* \tparam J The column number the manipulator will set the matrix assigner index to.
+* \return A static move_to matrix manipulator
+*
+* Example usage:
+* \code:
+* matrix<double> A(3, 3, 0);
+* A <<= 1, 2, move_to<2,2>, 3;
+* \endcode
+* will result in:
+* \code
+* 1 2 0
+* 0 0 0
+* 0 0 3
+* \endcode
+* \sa move_to(T i, T j) and static_matrix_move_to_manip
+*/
+template <std::size_t I, std::size_t J>
+BOOST_UBLAS_INLINE static_matrix_move_to_manip<I, J>  move_to() {
+    return static_matrix_move_to_manip<I, J>();
+}
+
+/**
+* \brief A move matrix index manipulator.
+*
+* When member function \c manip is called the manipulator's
+* index will be added to the referenced' index.
+*
+* \sa move(T i, T j)
+*/
+template <typename T>
+class matrix_move_manip: public index_manipulator<matrix_move_manip<T> > {
+public:
+    BOOST_UBLAS_INLINE
+    matrix_move_manip(T k, T l): i(k), j(l) { }
+
+    template <typename V, typename K>
+    BOOST_UBLAS_INLINE
+    void manip(V &k, K &l) const {
+        k+=i;
+        l+=j;
+    }
+private:
+    T i, j;
+};
+
+/**
+* \brief  An object generator that returns a move matrix index manipulator
+*
+* \tparam size type
+* \param i The number of rows the manipulator will traverse the index when "manip"
+* member function is called
+* \param j The number of columns the manipulator will traverse the index when "manip"
+* member function is called
+* \return A move matrix manipulator
+*
+* Example:
+* \code:
+* matrix<double> A(3, 3, 0);
+* A <<= 1, 2, move(1,0),
+*            3,;
+* \endcode
+* will result in:
+* \code
+* 1 2 0
+* 0 0 3
+* 0 0 0
+* \endcode
+*/
+template <typename T>
+BOOST_UBLAS_INLINE matrix_move_manip<T>  move(T i, T j) {
+    return matrix_move_manip<T>(i, j);
+}
+
+/**
+* \brief A static move matrix index manipulator.
+*
+* When member function traverse is called the manipulator's
+* index will be added to the referenced' index.
+*
+* \sa move()
+*
+* \todo Doxygen has some problems with similar template functions. Correct that.
+*/
+template <std::ptrdiff_t I, std::ptrdiff_t J>
+class static_matrix_move_manip: public index_manipulator<static_matrix_move_manip<I, J> > {
+public:
+    template <typename V, typename K>
+    BOOST_UBLAS_INLINE
+    void manip(V &k, K &l) const {
+        k+=I;
+        l+=J;
+    }
+};
+
+/**
+* \brief  An object generator that returns a static "move" matrix index manipulator.
+*
+* Typically faster than the dynamic version, but can be used only when the
+* values are known at compile time. Negative values can be used.
+* \tparam I The number of rows the manipulator will trasverse the matrix assigner index.
+* \tparam J The number of columns the manipulator will trasverse the matrix assigner index.
+* \tparam size type
+* \return A static move matrix manipulator
+*
+* Example:
+* \code:
+* matrix<double> A(3, 3, 0);
+* A <<= 1, 2, move<1,0>(),
+*            3,;
+* \endcode
+* will result in:
+* \code
+* 1 2 0
+* 0 0 3
+* 0 0 0
+* \endcode
+*
+* \sa move_to()
+*
+* \todo Doxygen has some problems with similar template functions. Correct that.
+*/
+template <std::ptrdiff_t I, std::ptrdiff_t J>
+BOOST_UBLAS_INLINE static_matrix_move_manip<I, J>  move() {
+    return static_matrix_move_manip<I, J>();
+}
+
+/**
+* \brief A begining of row manipulator
+*
+* When member function \c manip is called the referenced
+* index will be be set to the begining of the row (i.e. column = 0)
+*
+* \sa begin1()
+*/
+class begin1_manip: public index_manipulator<begin1_manip > {
+public:
+    template <typename V, typename K>
+    BOOST_UBLAS_INLINE
+    void manip(V & k, K &/*l*/) const {
+        k=0;
+    }
+};
+
+/**
+* \brief  An object generator that returns a begin1 manipulator.
+*
+* The resulted manipulator will traverse the index to the begining
+* of the current column when its' \c manip member function is called.
+*
+* \return A begin1 matrix index manipulator
+*
+* Example usage:
+* \code:
+* matrix<double> A(3, 3, 0);
+* A <<= 1, 2, next_row(),
+*      3, 4, begin1(), 1;
+* \endcode
+* will result in:
+* \code
+* 1 2 1
+* 3 4 0
+* 0 0 0
+* \endcode
+* \sa begin2()
+*/
+inline begin1_manip  begin1() {
+    return begin1_manip();
+}
+
+/**
+* \brief A begining of column manipulator
+*
+* When member function \c manip is called the referenced
+* index will be be set to the begining of the column (i.e. row = 0).
+*
+*
+* \sa begin2()
+*/
+class begin2_manip: public index_manipulator<begin2_manip > {
+public:
+    template <typename V, typename K>
+    BOOST_UBLAS_INLINE
+    void manip(V &/*k*/, K &l) const {
+        l=0;
+    }
+};
+
+/**
+* \brief  An object generator that returns a begin2 manipulator to be used to traverse a matrix.
+*
+* The resulted manipulator will traverse the index to the begining
+* of the current row when its' \c manip member function is called.
+*
+* \return A begin2 matrix manipulator
+*
+* Example:
+* \code:
+* matrix<double> A(3, 3, 0);
+* A <<= 1, 2, move<1,0>(),
+*      3, begin2(), 1;
+* \endcode
+* will result in:
+* \code
+* 1 2 0
+* 1 0 3
+* 0 0 0
+* \endcode
+* \sa begin1() begin2_manip
+*/
+inline begin2_manip  begin2() {
+    return begin2_manip();
+}
+
+
+/**
+* \brief A next row matrix manipulator.
+*
+* When member function traverse is called the referenced
+* index will be traveresed to the begining of next row.
+*
+* \sa next_row()
+*/
+class next_row_manip: public index_manipulator<next_row_manip> {
+public:
+    template <typename V, typename K>
+    BOOST_UBLAS_INLINE
+    void manip(V &k, K &l) const {
+        k++;
+        l=0;
+    }
+};
+
+/**
+* \brief  An object generator that returns a next_row manipulator.
+*
+* The resulted manipulator will traverse the index to the begining
+* of the next row when it's manip member function is called.
+*
+* \return A next_row matrix manipulator.
+*
+* Example:
+* \code:
+* matrix<double> A(3, 3, 0);
+* A <<= 1, 2, next_row(),
+*      3, 4;
+* \endcode
+* will result in:
+* \code
+* 1 2 0
+* 3 4 0
+* 0 0 0
+* \endcode
+* \sa next_column()
+*/
+inline next_row_manip  next_row() {
+    return next_row_manip();
+}
+
+/**
+* \brief A next column matrix manipulator.
+*
+* When member function traverse is called the referenced
+* index will be traveresed to the begining of next column.
+*
+* \sa next_column()
+*/
+class next_column_manip: public index_manipulator<next_column_manip> {
+public:
+    template <typename V, typename K>
+    BOOST_UBLAS_INLINE
+    void manip(V &k, K &l) const {
+        k=0;
+        l++;
+    }
+};
+
+/**
+* \brief  An object generator that returns a next_row manipulator.
+*
+* The resulted manipulator will traverse the index to the begining
+* of the next column when it's manip member function is called.
+*
+* \return A next_column matrix manipulator.
+*
+* Example:
+* \code:
+* matrix<double> A(3, 3, 0);
+* A <<= 1, 2, 0,
+*      3, next_column(), 4;
+* \endcode
+* will result in:
+* \code
+* 1 2 4
+* 3 0 0
+* 0 0 0
+* \endcode
+*
+*/
+inline next_column_manip next_column() {
+    return next_column_manip();
+}
+
+/**
+* \brief  A wrapper for fill policy classes
+*
+*/
+template <class T>
+class fill_policy_wrapper {
+public:
+    typedef T type;
+};
+
+// Collection of the fill policies
+namespace fill_policy {
+
+    /**
+    * \brief  An index assign policy
+    *
+    * This policy is used to for the simplified ublas assign through
+    * normal indexing.
+    *
+    *
+    */
+    class index_assign :public fill_policy_wrapper<index_assign> {
+    public:
+        template <class T, typename S, typename V>
+        BOOST_UBLAS_INLINE
+        static void apply(T &e, const S &i, const V &v) {
+            e()(i) = v;
+        }
+        template <class T, typename S, typename V>
+        BOOST_UBLAS_INLINE
+        static void apply(T &e, const S &i, const S &j, const V &v) {
+            e()(i, j) = v;
+        }
+    };
+
+    /**
+    * \brief  An index plus assign policy
+    *
+    * This policy is used when the assignment is desired to be followed
+    * by an addition.
+    *
+    *
+    */
+    class index_plus_assign :public fill_policy_wrapper<index_plus_assign> {
+    public:
+        template <class T, typename S, typename V>
+        BOOST_UBLAS_INLINE
+        static void apply(T &e, const S &i, const V &v) {
+            e()(i) += v;
+        }
+        template <class T, typename S, typename V>
+        BOOST_UBLAS_INLINE
+        static void apply(T &e, const S &i, const S &j, const V &v) {
+            e()(i, j) += v;
+        }
+    };
+
+    /**
+    * \brief  An index minus assign policy
+    *
+    * This policy is used when the assignment is desired to be followed
+    * by a substraction.
+    *
+    *
+    */
+    class index_minus_assign :public fill_policy_wrapper<index_minus_assign> {
+    public:
+        template <class T, typename S, typename V>
+        BOOST_UBLAS_INLINE
+        static void apply(T &e, const S &i, const V &v) {
+            e()(i) -= v;
+        }
+        template <class T, typename S, typename V>
+        BOOST_UBLAS_INLINE
+        static void apply(T &e, const S &i, const S &j, const V &v) {
+            e()(i, j) -= v;
+        }
+    };
+
+    /**
+    * \brief  The sparse push_back fill policy.
+    *
+    * This policy is adequate for sparse types, when fast filling is required, where indexing
+    * assign is pretty slow.
+
+    * It is important to note that push_back assign cannot be used to add elements before elements
+    * already existing in a sparse container. To achieve that please use the sparse_insert fill policy.
+    */
+    class sparse_push_back :public fill_policy_wrapper<sparse_push_back > {
+    public:
+        template <class T, class S, class V>
+        BOOST_UBLAS_INLINE
+        static void apply(T &e, const S &i, const V &v) {
+            e().push_back(i, v);
+        }
+        template <class T, class S, class V>
+        BOOST_UBLAS_INLINE
+        static void apply(T &e, const S &i, const S &j, const V &v) {
+            e().push_back(i,j, v);
+        }
+    };
+
+    /**
+    * \brief  The sparse insert fill policy.
+    *
+    * This policy is adequate for sparse types, when fast filling is required, where indexing
+    * assign is pretty slow. It is slower than sparse_push_back fill policy, but it can be used to
+    * insert elements anywhere inside the container.
+    */
+    class sparse_insert :public fill_policy_wrapper<sparse_insert> {
+    public:
+        template <class T, class S, class V>
+        BOOST_UBLAS_INLINE
+        static void apply(T &e, const S &i, const V &v) {
+            e().insert_element(i, v);
+        }
+        template <class T, class S, class V>
+        BOOST_UBLAS_INLINE
+        static void apply(T &e, const S &i, const S &j, const V &v) {
+            e().insert_element(i,j, v);
+        }
+    };
+
+}
+
+/** \brief A wrapper for traverse policy classes
+*
+*/
+template <class T>
+class traverse_policy_wrapper {
+public:
+    typedef T type;
+};
+
+// Collection of the traverse policies
+namespace traverse_policy {
+
+
+    /**
+    * \brief  The no wrap policy.
+    *
+    * The no wrap policy does not allow wrapping when assigning to a matrix
+    */
+    struct no_wrap {
+        /**
+        * \brief  Element wrap method
+        */
+        template <class S1, class S2, class S3>
+        BOOST_UBLAS_INLINE
+        static void apply1(const S1 &/*s*/, S2 &/*i*/, S3 &/*j*/) {
+        }
+
+        /**
+        * \brief  Matrix block wrap method
+        */
+        template <class S1, class S2, class S3>
+        BOOST_UBLAS_INLINE
+        static void apply2(const S1 &/*s1*/, const S1 &/*s2*/, S2 &/*i1*/, S3 &/*i2*/) {
+        }
+    };
+
+    /**
+    * \brief  The wrap policy.
+    *
+    * The wrap policy enables element wrapping when assigning to a matrix
+    */
+    struct wrap {
+        /**
+        * \brief  Element wrap method
+        */
+        template <class S1, class S2, class S3>
+        BOOST_UBLAS_INLINE
+        static void apply1(const S1 &s, S2 &i1, S3 &i2) {
+            if (i2>=s) {
+                i1++;
+                i2=0;
+            }
+        }
+
+        /**
+        * \brief  Matrix block wrap method
+        */
+        template <class S1, class S2, class S3>
+        BOOST_UBLAS_INLINE
+        static void apply2(const S1 &s1, const S1 &s2, S2 &i1, S3 &i2) {
+            if (i2>=s2) i2=0;   // Wrap to the next block
+            else i1-=s1;        // Move up (or right) one block
+        }
+    };
+
+    /**
+    * \brief  The row_by_row traverse policy
+    *
+    * This policy is used when the assignment is desired to happen
+    * row_major wise for performance or other reasons.
+    *
+    * This is the default behaviour. To change it globally please define BOOST_UBLAS_DEFAULT_ASSIGN_BY_COLUMN
+    * in the compilation options or in an adequate header file.
+    *
+    * Please see EXAMPLES_LINK for usage information.
+    *
+    * \todo Add examples link
+    */
+    template <class Wrap = wrap>
+    class by_row_policy :public traverse_policy_wrapper<by_row_policy<Wrap> > {
+    public:
+        template <typename S1, typename S2>
+        BOOST_UBLAS_INLINE
+        static void advance(S1 &/*i*/, S2 &j) { j++;}
+
+        template <class E1, class E2, typename S1, typename S2, typename S3, typename S4, typename S5>
+        BOOST_UBLAS_INLINE
+        static bool next(const E1 &e, const E2 &me, S1 &i, S2 &j, const S3 &/*i0*/, const S3 &j0, S4 &k, S5 &l) {
+            l++; j++;
+            if (l>=e().size2()) {
+                l=0; k++; j=j0; i++;
+                // It is assumed that the iteration starts from 0 and progresses only using this function from within
+                // an assigner object.
+                // Otherwise (i.e. if it is called outside the assigner object) apply2 should have been
+                // outside the if statement.
+                if (k>=e().size1()) {
+                    j=j0+e().size2();
+                    Wrap::apply2(e().size1(), me().size2(), i, j);
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        template <class E, typename S1, typename S2>
+        BOOST_UBLAS_INLINE
+        static void apply_wrap(const E& e, S1 &i, S2 &j) {
+            Wrap::apply1(e().size2(), i, j);
+        }
+    };
+
+    /**
+    * \brief  The column_by_column traverse policy
+    *
+    * This policy is used when the assignment is desired to happen
+    * column_major wise, for performance or other reasons.
+    *
+    * This is the NOT the default behaviour. To set this as the default define BOOST_UBLAS_DEFAULT_ASSIGN_BY_COLUMN
+    * in the compilation options or in an adequate header file.
+    *
+    * Please see EXAMPLES_LINK for usage information.
+    *
+    * \todo Add examples link
+    */
+    template <class Wrap = wrap>
+    class by_column_policy :public traverse_policy_wrapper<by_column_policy<Wrap> > {
+    public:
+        template <typename S1, typename S2>
+        BOOST_UBLAS_INLINE
+        static void advance(S1 &i, S2 &/*j*/) { i++;}
+
+        template <class E1, class E2, typename S1, typename S2, typename S3, typename S4, typename S5>
+        BOOST_UBLAS_INLINE
+        static bool next(const E1 &e, const E2 &me, S1 &i, S2 &j, const S3 &i0, const S3 &/*j0*/, S4 &k, S5 &l) {
+            k++; i++;
+            if (k>=e().size1()) {
+                k=0; l++; i=i0; j++;
+                // It is assumed that the iteration starts from 0 and progresses only using this function from within
+                // an assigner object.
+                // Otherwise (i.e. if it is called outside the assigner object) apply2 should have been
+                // outside the if statement.
+                if (l>=e().size2()) {
+                    i=i0+e().size1();
+                    Wrap::apply2(e().size2(), me().size1(), j, i);
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        template <class E, typename S1, typename S2>
+        BOOST_UBLAS_INLINE
+        static void apply_wrap(const E& e, S1 &i, S2 &j) {
+            Wrap::apply1(e().size1(), j, i);
+        }
+    };
+}
+#ifndef BOOST_UBLAS_DEFAULT_NO_WRAP_POLICY
+    typedef traverse_policy::wrap DEFAULT_WRAP_POLICY;
+#else
+    typedef traverse_policy::no_wrap DEFAULT_WRAP_POLICY;
+#endif
+
+#ifndef BOOST_UBLAS_DEFAULT_ASSIGN_BY_COLUMN
+    typedef traverse_policy::by_row_policy<DEFAULT_WRAP_POLICY> DEFAULT_TRAVERSE_POLICY;
+#else
+    typedef traverse_policy::by_column<DEFAULT_WRAP_POLICY> DEFAULT_TRAVERSE_POLICY;
+#endif
+
+ // Traverse policy namespace
+namespace traverse_policy {
+
+    inline by_row_policy<DEFAULT_WRAP_POLICY> by_row() {
+    return by_row_policy<DEFAULT_WRAP_POLICY>();
+    }
+
+    inline by_row_policy<wrap> by_row_wrap() {
+        return by_row_policy<wrap>();
+    }
+
+    inline by_row_policy<no_wrap> by_row_no_wrap() {
+        return by_row_policy<no_wrap>();
+    }
+
+    inline by_column_policy<DEFAULT_WRAP_POLICY> by_column() {
+        return by_column_policy<DEFAULT_WRAP_POLICY>();
+    }
+
+    inline by_column_policy<wrap> by_column_wrap() {
+        return by_column_policy<wrap>();
+    }
+
+    inline by_column_policy<no_wrap> by_column_no_wrap() {
+        return by_column_policy<no_wrap>();
+    }
+
+}
+
+/**
+* \brief  An assigner object used to fill a vector using operator <<= and operator, (comma)
+*
+* This object is meant to be created by appropriate object generators.
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E, class Fill_Policy = fill_policy::index_assign>
+class vector_expression_assigner {
+public:
+    typedef typename E::expression_type::value_type value_type;
+    typedef typename E::expression_type::size_type size_type;
+
+    BOOST_UBLAS_INLINE
+    vector_expression_assigner(E &e):ve(e), i(0) {
+    }
+
+    BOOST_UBLAS_INLINE
+    vector_expression_assigner(size_type k, E &e):ve(e), i(k) {
+        // Overloaded like that so it can be differentiated from (E, val).
+        // Otherwise there would be an ambiquity when value_type == size_type.
+    }
+
+    BOOST_UBLAS_INLINE
+    vector_expression_assigner(E &e, value_type val):ve(e), i(0) {
+        operator,(val);
+    }
+
+    template <class AE>
+    BOOST_UBLAS_INLINE
+    vector_expression_assigner(E &e, const vector_expression<AE> &nve):ve(e), i(0) {
+        operator,(nve);
+    }
+
+    template <typename T>
+    BOOST_UBLAS_INLINE
+    vector_expression_assigner(E &e, const index_manipulator<T> &ta):ve(e), i(0) {
+        operator,(ta);
+    }
+
+    BOOST_UBLAS_INLINE
+    vector_expression_assigner &operator, (const value_type& val) {
+        apply(val);
+        return *this;
+    }
+
+    template <class AE>
+    BOOST_UBLAS_INLINE
+    vector_expression_assigner &operator, (const vector_expression<AE> &nve) {
+        for (typename AE::size_type k = 0; k!= nve().size(); k++)
+            operator,(nve()(k));
+        return *this;
+    }
+
+    template <typename T>
+    BOOST_UBLAS_INLINE
+    vector_expression_assigner &operator, (const index_manipulator<T> &ta) {
+        ta().manip(i);
+        return *this;
+    }
+
+    template <class T>
+    BOOST_UBLAS_INLINE
+    vector_expression_assigner<E, T> operator, (fill_policy_wrapper<T>) const {
+        return vector_expression_assigner<E, T>(i, ve);
+    }
+
+private:
+    BOOST_UBLAS_INLINE
+    vector_expression_assigner &apply(const typename E::expression_type::value_type& val) {
+        Fill_Policy::apply(ve, i++, val);
+        return *this;
+    }
+
+private:
+    E &ve;
+    size_type i;
+};
+
+/*
+// The following static assigner is about 30% slower than the dynamic one, probably due to the recursive creation of assigner objects.
+// It remains commented here for future reference.
+
+template <class E, std::size_t I=0>
+class static_vector_expression_assigner {
+public:
+    typedef typename E::expression_type::value_type value_type;
+    typedef typename E::expression_type::size_type size_type;
+
+    BOOST_UBLAS_INLINE
+    static_vector_expression_assigner(E &e):ve(e) {
+    }
+
+    BOOST_UBLAS_INLINE
+    static_vector_expression_assigner(E &e, value_type val):ve(e) {
+        operator,(val);
+    }
+
+    BOOST_UBLAS_INLINE
+    static_vector_expression_assigner<E, I+1> operator, (const value_type& val) {
+        return apply(val);
+    }
+
+private:
+    BOOST_UBLAS_INLINE
+    static_vector_expression_assigner<E, I+1> apply(const typename E::expression_type::value_type& val) {
+        ve()(I)=val;
+        return static_vector_expression_assigner<E, I+1>(ve);
+    }
+
+private:
+    E &ve;
+};
+
+template <class E>
+BOOST_UBLAS_INLINE
+static_vector_expression_assigner<vector_expression<E>, 1 > test_static(vector_expression<E> &v, const typename E::value_type &val) {
+    v()(0)=val;
+    return static_vector_expression_assigner<vector_expression<E>, 1 >(v);
+}
+*/
+
+
+/**
+* \brief  A vector_expression_assigner generator used with operator<<= for simple types
+*
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E>
+BOOST_UBLAS_INLINE
+vector_expression_assigner<vector_expression<E> > operator<<=(vector_expression<E> &v, const typename E::value_type &val) {
+    return vector_expression_assigner<vector_expression<E> >(v,val);
+}
+
+/**
+* \brief  ! A vector_expression_assigner generator used with operator<<= for vector expressions
+*
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E1, class E2>
+BOOST_UBLAS_INLINE
+vector_expression_assigner<vector_expression<E1> > operator<<=(vector_expression<E1> &v, const vector_expression<E2> &ve) {
+    return vector_expression_assigner<vector_expression<E1> >(v,ve);
+}
+
+/**
+* \brief  A vector_expression_assigner generator used with operator<<= for traverse manipulators
+*
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E, typename T>
+BOOST_UBLAS_INLINE
+vector_expression_assigner<vector_expression<E> > operator<<=(vector_expression<E> &v, const index_manipulator<T> &nv) {
+    return vector_expression_assigner<vector_expression<E> >(v,nv);
+}
+
+/**
+* \brief  A vector_expression_assigner generator used with operator<<= for choice of fill policy
+*
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E, typename T>
+BOOST_UBLAS_INLINE
+vector_expression_assigner<vector_expression<E>, T> operator<<=(vector_expression<E> &v, fill_policy_wrapper<T>) {
+    return vector_expression_assigner<vector_expression<E>, T>(v);
+}
+
+/**
+* \brief  An assigner object used to fill a vector using operator <<= and operator, (comma)
+*
+* This object is meant to be created by appropriate object generators.
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E, class Fill_Policy = fill_policy::index_assign, class Traverse_Policy = DEFAULT_TRAVERSE_POLICY >
+class matrix_expression_assigner {
+public:
+    typedef typename E::expression_type::size_type size_type;
+
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner(E &e): me(e), i(0), j(0) {
+    }
+
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner(E &e, size_type k, size_type l): me(e), i(k), j(l) {
+    }
+
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner(E &e, typename E::expression_type::value_type val): me(e), i(0), j(0) {
+        operator,(val);
+    }
+
+    template <class AE>
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner(E &e, const vector_expression<AE> &nve):me(e), i(0), j(0) {
+        operator,(nve);
+    }
+
+    template <class AE>
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner(E &e, const matrix_expression<AE> &nme):me(e), i(0), j(0) {
+        operator,(nme);
+    }
+
+    template <typename T>
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner(E &e, const index_manipulator<T> &ta):me(e), i(0), j(0) {
+        operator,(ta);
+    }
+
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner &operator, (const typename E::expression_type::value_type& val) {
+        Traverse_Policy::apply_wrap(me, i ,j);
+        return apply(val);
+    }
+
+    template <class AE>
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner &operator, (const vector_expression<AE> &nve) {
+        for (typename AE::size_type k = 0; k!= nve().size(); k++) {
+            operator,(nve()(k));
+        }
+        return *this;
+    }
+
+    template <class AE>
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner &operator, (const matrix_expression<AE> &nme) {
+        return apply(nme);
+    }
+
+    template <typename T>
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner &operator, (const index_manipulator<T> &ta) {
+        ta().manip(i, j);
+        return *this;
+    } 
+
+    template <class T>
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner<E, T, Traverse_Policy> operator, (fill_policy_wrapper<T>) const {
+        return matrix_expression_assigner<E, T, Traverse_Policy>(me, i, j);
+    }
+
+
+    template <class T>
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner<E, Fill_Policy, T> operator, (traverse_policy_wrapper<T>) {
+        Traverse_Policy::apply_wrap(me, i ,j);
+        return matrix_expression_assigner<E, Fill_Policy, T>(me, i, j);
+    }
+
+private:
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner &apply(const typename E::expression_type::value_type& val) {
+        Fill_Policy::apply(me, i, j, val);
+        Traverse_Policy::advance(i,j);
+        return *this;
+    }
+
+    template <class AE>
+    BOOST_UBLAS_INLINE
+    matrix_expression_assigner &apply(const matrix_expression<AE> &nme) {
+        size_type bi = i;
+        size_type bj = j;
+        typename AE::size_type k=0, l=0;
+        Fill_Policy::apply(me, i, j, nme()(k, l));
+        while (Traverse_Policy::next(nme, me, i, j, bi, bj, k, l))
+            Fill_Policy::apply(me, i, j, nme()(k, l));
+        return *this;
+    }
+
+private:
+    E &me;
+    size_type i, j;
+};
+
+/**
+* \brief  A matrix_expression_assigner generator used with operator<<= for simple types
+*
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E>
+BOOST_UBLAS_INLINE
+matrix_expression_assigner<matrix_expression<E> > operator<<=(matrix_expression<E> &me, const typename E::value_type &val) {
+    return matrix_expression_assigner<matrix_expression<E> >(me,val);
+}
+
+/**
+* \brief  A matrix_expression_assigner generator used with operator<<= for choice of fill policy
+*
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E, typename T>
+BOOST_UBLAS_INLINE
+matrix_expression_assigner<matrix_expression<E>, T> operator<<=(matrix_expression<E> &me, fill_policy_wrapper<T>) {
+    return matrix_expression_assigner<matrix_expression<E>, T>(me);
+}
+
+/**
+* \brief  A matrix_expression_assigner generator used with operator<<= for traverse manipulators
+*
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E, typename T>
+BOOST_UBLAS_INLINE
+matrix_expression_assigner<matrix_expression<E> > operator<<=(matrix_expression<E> &me, const index_manipulator<T> &ta) {
+    return matrix_expression_assigner<matrix_expression<E> >(me,ta);
+}
+
+/**
+* \brief  A matrix_expression_assigner generator used with operator<<= for traverse manipulators
+*
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E, typename T>
+BOOST_UBLAS_INLINE
+matrix_expression_assigner<matrix_expression<E>, fill_policy::index_assign, T> operator<<=(matrix_expression<E> &me, traverse_policy_wrapper<T>) {
+    return matrix_expression_assigner<matrix_expression<E>, fill_policy::index_assign, T>(me);
+}
+
+/**
+* \brief  A matrix_expression_assigner generator used with operator<<= for vector expressions
+*
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E1, class E2>
+BOOST_UBLAS_INLINE
+matrix_expression_assigner<matrix_expression<E1> > operator<<=(matrix_expression<E1> &me, const vector_expression<E2> &ve) {
+    return matrix_expression_assigner<matrix_expression<E1> >(me,ve);
+}
+
+/**
+* \brief  A matrix_expression_assigner generator used with operator<<= for matrix expressions
+*
+* Please see EXAMPLES_LINK for usage information.
+*
+* \todo Add examples link
+*/
+template <class E1, class E2>
+BOOST_UBLAS_INLINE
+matrix_expression_assigner<matrix_expression<E1> > operator<<=(matrix_expression<E1> &me1, const matrix_expression<E2> &me2) {
+    return matrix_expression_assigner<matrix_expression<E1> >(me1,me2);
+}
+
+} } }
+
+#endif // ASSIGNMENT_HPP
diff --git a/include/boost/numeric/ublas/banded.hpp b/include/boost/numeric/ublas/banded.hpp
new file mode 100644
index 0000000..d135650
--- /dev/null
+++ b/include/boost/numeric/ublas/banded.hpp
@@ -0,0 +1,2372 @@
+//
+//  Copyright (c) 2000-2013
+//  Joerg Walter, Mathias Koch, Athanasios Iliopoulos
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_BANDED_
+#define _BOOST_UBLAS_BANDED_
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/detail/temporary.hpp>
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+
+
+namespace hidden {
+
+
+
+/** \brief A helper for band_matrix indexing.
+ *
+ * The indexing happens as per the netlib description: http://www.netlib.org/lapack/lug/node124.html.
+ * In the case of a row_major matrix a different approach is followed;
+ */
+template <class LayoutType>
+class banded_indexing { };
+
+/** \brief A helper for indexing column major banded matrices.
+ *
+ */
+template <>
+class banded_indexing<column_major_tag> {
+public:
+
+    template <class T>
+    BOOST_UBLAS_INLINE static T size(T /*size1*/, T size2) {
+        return size2;
+    }
+
+//    template <class T>
+//    BOOST_UBLAS_INLINE static bool valid_index(T size1, T /*size2*/, T lower, T upper, T i, T j) {
+//        return (upper+i >= j) && i <= std::min(size1 - 1, j + lower); // upper + i is used by get_index. Maybe find a way to consolidate the operations to increase performance
+//    }
+
+    template <class T>
+    BOOST_UBLAS_INLINE static T get_index(T /*size1*/, T size2, T lower, T upper, T i, T j) {
+        return column_major::element (upper + i - j, lower + 1 + upper, j, size2);
+    }
+};
+
+/** \brief A helper for indexing row major banded matrices.
+ *
+ */
+template <>
+class banded_indexing<row_major_tag> {
+public:
+
+    template <class T>
+    BOOST_UBLAS_INLINE static T size(T size1, T /*size2*/) {
+        return size1;
+    }
+
+  //  template <class T>
+  //  BOOST_UBLAS_INLINE static bool valid_index(T /*size1*/, T  size2, T lower, T upper, T i, T j) {
+  //      return (lower+j >= i) && j <= std::min(size2 - 1, i + upper); // lower + j is used by get_index. Maybe find a way to consolidate the operations to increase performance
+  //  }
+
+    template <class T>
+    BOOST_UBLAS_INLINE static T get_index(T size1, T /*size2*/, T lower, T upper, T i, T j) {
+        return row_major::element (i, size1, lower + j - i, lower + 1 + upper);
+    }
+};
+
+}
+
+    /** \brief A banded matrix of values of type \c T.
+     *
+     * For a \f$(mxn)\f$-dimensional banded matrix with \f$l\f$ lower and \f$u\f$ upper diagonals and 
+     * \f$0 \leq i < m\f$ and \f$0 \leq j < n\f$, if \f$i>j+l\f$ or \f$i<j-u\f$ then \f$b_{i,j}=0\f$. 
+     * The default storage for banded matrices is packed. Orientation and storage can also be specified. 
+     * Default is \c row_major and and unbounded_array. It is \b not required by the storage to initialize 
+     * elements of the matrix.
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+     * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
+     * \tparam A the type of Storage array. Default is \c unbounded_array
+     */
+    template<class T, class L, class A>
+    class banded_matrix:
+        public matrix_container<banded_matrix<T, L, A> > {
+
+        typedef T *pointer;
+        typedef L layout_type;
+        typedef banded_matrix<T, L, A> self_type;
+
+
+
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef A array_type;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef vector<T, A> vector_temporary_type;
+        typedef matrix<T, L, A> matrix_temporary_type;  // general sub-matrix
+        typedef packed_tag storage_category;
+        typedef typename L::orientation_category orientation_category;
+
+    private:
+    public:
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        banded_matrix ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0),
+            lower_ (0), upper_ (0), data_ (0) {}
+        BOOST_UBLAS_INLINE
+        banded_matrix (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2),
+            lower_ (lower), upper_ (upper),
+#if defined(BOOST_UBLAS_OWN_BANDED) || (BOOST_UBLAS_LEGACY_BANDED)
+            data_ ((std::max) (size1, size2) * (lower + 1 + upper))
+#else
+            data_ ( hidden::banded_indexing<orientation_category>::size(size1, size2) * (lower + 1 + upper)) // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
+#endif
+        {
+        }
+        BOOST_UBLAS_INLINE
+        banded_matrix (size_type size1, size_type size2, size_type lower, size_type upper, const array_type &data):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2),
+            lower_ (lower), upper_ (upper), data_ (data) {}
+        BOOST_UBLAS_INLINE
+        banded_matrix (const banded_matrix &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_),
+            lower_ (m.lower_), upper_ (m.upper_), data_ (m.data_) {}
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_matrix (const matrix_expression<AE> &ae, size_type lower = 0, size_type upper = 0):
+            matrix_container<self_type> (),
+            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()),
+            lower_ (lower), upper_ (upper),
+#if defined(BOOST_UBLAS_OWN_BANDED) || (BOOST_UBLAS_LEGACY_BANDED)
+            data_ ((std::max) (size1_, size2_) * (lower_ + 1 + upper_))
+#else
+            data_ ( hidden::banded_indexing<orientation_category>::size(size1_, size2_) * (lower_ + 1 + upper_)) // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
+#endif
+        {
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type lower () const {
+            return lower_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type upper () const {
+            return upper_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const array_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+#if !defined (BOOST_UBLAS_OWN_BANDED)||(BOOST_UBLAS_LEGACY_BANDED)
+        BOOST_UBLAS_INLINE
+        bool is_element_in_band(size_type i, size_type j) const{
+            //return (upper_+i >= j) && i <= std::min(size1() - 1, j + lower_); // We don't need to check if i is outside because it is checked anyway in the accessors.
+            return (upper_+i >= j) && i <= ( j + lower_); // Essentially this band has "infinite" positive dimensions
+        }
+#endif
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0, bool preserve = true) {
+            if (preserve) {
+                self_type temporary (size1, size2, lower, upper);
+                detail::matrix_resize_preserve<layout_type> (*this, temporary);
+            }
+            else {
+                data ().resize ((std::max) (size1, size2) * (lower + 1 + upper));
+                size1_ = size1;
+                size2_ = size2;
+                lower_ = lower;
+                upper_ = upper;
+            }
+        }
+
+        BOOST_UBLAS_INLINE
+        void resize_packed_preserve (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0) {
+            size1_ = size1;
+            size2_ = size2;
+            lower_ = lower;
+            upper_ = upper;
+            data ().resize ((std::max) (size1, size2) * (lower + 1 + upper), value_type ());
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
+#ifdef BOOST_UBLAS_OWN_BANDED
+            const size_type k = (std::max) (i, j);
+            const size_type l = lower_ + j - i;
+            if (k < (std::max) (size1_, size2_) && // TODO: probably use BOOST_UBLAS_CHECK here instead of if
+                l < lower_ + 1 + upper_)
+                return data () [layout_type::element (k, (std::max) (size1_, size2_),
+                                                       l, lower_ + 1 + upper_)];
+#elif BOOST_UBLAS_LEGACY_BANDED // Prior to version: TODO: add version this is actually incorporated in
+            const size_type k = j;
+            const size_type l = upper_ + i - j;
+            if (k < size2_ &&
+                l < lower_ + 1 + upper_)
+                return data () [layout_type::element (k, size2_,
+                                                       l, lower_ + 1 + upper_)];
+#else  // New default
+            // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
+            if ( is_element_in_band( i, j) ) {
+                return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
+            }
+#endif
+            return zero_;
+        }
+
+        BOOST_UBLAS_INLINE
+        reference at_element (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
+#ifdef BOOST_UBLAS_OWN_BANDED
+            const size_type k = (std::max) (i, j);
+            const size_type l = lower_ + j - i; // TODO: Don't we need an if or BOOST_UBLAS_CHECK HERE?
+            return data () [layout_type::element (k, (std::max) (size1_, size2_),
+                                                   l, lower_ + 1 + upper_)];
+#elif BOOST_UBLAS_LEGACY_BANDED // Prior to version: TODO: add version this is actually incorporated in
+            const size_type k = j;
+            const size_type l = upper_ + i - j;
+            if (! (k < size2_ &&
+                   l < lower_ + 1 + upper_) ) {
+                bad_index ().raise ();
+                // NEVER reached
+            }
+            return data () [layout_type::element (k, size2_,
+                                                       l, lower_ + 1 + upper_)];
+#else
+            // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
+            BOOST_UBLAS_CHECK(is_element_in_band( i, j) , bad_index());
+            return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
+#ifdef BOOST_UBLAS_OWN_BANDED
+            const size_type k = (std::max) (i, j);
+            const size_type l = lower_ + j - i;
+            if (! (k < (std::max) (size1_, size2_) && // TODO: probably use BOOST_UBLAS_CHECK here instead of if
+                  l < lower_ + 1 + upper_) ) {
+                bad_index ().raise ();
+                // NEVER reached
+            }
+            return data () [layout_type::element (k, (std::max) (size1_, size2_),
+                                                       l, lower_ + 1 + upper_)];
+#elif BOOST_UBLAS_LEGACY_BANDED // Prior to version: TODO: add version this is actually incorporated in
+            const size_type k = j;
+            const size_type l = upper_ + i - j;
+            if (! (k < size2_ &&
+                   l < lower_ + 1 + upper_) ) {
+                bad_index ().raise ();
+                // NEVER reached
+            }
+            return data () [layout_type::element (k, size2_,
+                                                       l, lower_ + 1 + upper_)];
+#else
+            // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
+            BOOST_UBLAS_CHECK( is_element_in_band( i, j) , bad_index());
+            return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
+#endif
+
+        }
+
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        reference insert_element (size_type i, size_type j, const_reference t) {
+            return (operator () (i, j) = t);
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i, size_type j) {
+            operator () (i, j) = value_type/*zero*/();
+        }
+
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        banded_matrix &operator = (const banded_matrix &m) {
+            size1_ = m.size1_;
+            size2_ = m.size2_;
+            lower_ = m.lower_;
+            upper_ = m.upper_;
+            data () = m.data ();
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        banded_matrix &assign_temporary (banded_matrix &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_matrix &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae, lower_, upper_);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_matrix &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_matrix& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae, lower_, upper_);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_matrix &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_matrix& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae, lower_, upper_);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_matrix &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        banded_matrix& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        banded_matrix& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (banded_matrix &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                std::swap (lower_, m.lower_);
+                std::swap (upper_, m.upper_);
+                data ().swap (m.data ());
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (banded_matrix &m1, banded_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            if (rank == 1) {
+                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
+                i = (std::max) (i, lower_i);
+                size_type upper_i = (std::min) (j + 1 + lower_, size1_);
+                i = (std::min) (i, upper_i);
+            }
+            return const_iterator1 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int rank, size_type i, size_type j) {
+            if (rank == 1) {
+                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
+                i = (std::max) (i, lower_i);
+                size_type upper_i = (std::min) (j + 1 + lower_, size1_);
+                i = (std::min) (i, upper_i);
+            }
+            return iterator1 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            if (rank == 1) {
+                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
+                j = (std::max) (j, lower_j);
+                size_type upper_j = (std::min) (i + 1 + upper_, size2_);
+                j = (std::min) (j, upper_j);
+            }
+            return const_iterator2 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int rank, size_type i, size_type j) {
+            if (rank == 1) {
+                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
+                j = (std::max) (j, lower_j);
+                size_type upper_j = (std::min) (i + 1 + upper_, size2_);
+                j = (std::min) (j, upper_j);
+            }
+            return iterator2 (*this, i, j);
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<banded_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename banded_matrix::value_type value_type;
+            typedef typename banded_matrix::difference_type difference_type;
+            typedef typename banded_matrix::const_reference reference;
+            typedef const typename banded_matrix::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, size_type it1, size_type it2):
+                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, it1_, 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<banded_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename banded_matrix::value_type value_type;
+            typedef typename banded_matrix::difference_type difference_type;
+            typedef typename banded_matrix::reference reference;
+            typedef typename banded_matrix::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, size_type it1, size_type it2):
+                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return (*this) ().at_element (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                return (*this) ().find2 (1, it1_, 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
+            }
+
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1_, 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<banded_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename banded_matrix::value_type value_type;
+            typedef typename banded_matrix::difference_type difference_type;
+            typedef typename banded_matrix::const_reference reference;
+            typedef const typename banded_matrix::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, size_type it1, size_type it2):
+                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end();
+            }
+
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<banded_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename banded_matrix::value_type value_type;
+            typedef typename banded_matrix::difference_type difference_type;
+            typedef typename banded_matrix::reference reference;
+            typedef typename banded_matrix::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, size_type it1, size_type it2):
+                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return (*this) ().at_element (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                return (*this) ().find1 (1, 0, it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        size_type size1_;
+        size_type size2_;
+        size_type lower_;
+        size_type upper_;
+        array_type data_;
+        typedef const value_type const_value_type;
+        static const_value_type zero_;
+    };
+
+    template<class T, class L, class A>
+    typename banded_matrix<T, L, A>::const_value_type banded_matrix<T, L, A>::zero_ = value_type/*zero*/();
+
+
+    /** \brief A diagonal matrix of values of type \c T, which is a specialization of a banded matrix
+     *
+     * For a \f$(m\times m)\f$-dimensional diagonal matrix, \f$0 \leq i < m\f$ and \f$0 \leq j < m\f$, 
+     * if \f$i\neq j\f$ then \f$b_{i,j}=0\f$. The default storage for diagonal matrices is packed. 
+     * Orientation and storage can also be specified. Default is \c row major \c unbounded_array. 
+     *
+     * As a specialization of a banded matrix, the constructor of the diagonal matrix creates 
+     * a banded matrix with 0 upper and lower diagonals around the main diagonal and the matrix is 
+     * obviously a square matrix. Operations are optimized based on these 2 assumptions. It is 
+     * \b not required by the storage to initialize elements of the matrix.  
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+     * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
+     * \tparam A the type of Storage array. Default is \c unbounded_array
+     */
+    template<class T, class L, class A>
+    class diagonal_matrix:
+        public banded_matrix<T, L, A> {
+    public:
+        typedef typename A::size_type size_type;
+        typedef banded_matrix<T, L, A> matrix_type;
+        typedef A array_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        diagonal_matrix ():
+            matrix_type () {}
+        BOOST_UBLAS_INLINE
+        diagonal_matrix (size_type size):
+            matrix_type (size, size) {}
+        BOOST_UBLAS_INLINE
+        diagonal_matrix (size_type size, const array_type& data):
+            matrix_type (size, size, 0, 0, data) {}
+        BOOST_UBLAS_INLINE
+        diagonal_matrix (size_type size1, size_type size2):
+            matrix_type (size1, size2) {}
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        diagonal_matrix (const matrix_expression<AE> &ae):
+            matrix_type (ae) {}
+        BOOST_UBLAS_INLINE
+        ~diagonal_matrix () {}
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        diagonal_matrix &operator = (const diagonal_matrix &m) {
+            matrix_type::operator = (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        diagonal_matrix &operator = (const matrix_expression<AE> &ae) {
+            matrix_type::operator = (ae);
+            return *this;
+        }
+    };
+
+    /** \brief A banded matrix adaptator: convert a any matrix into a banded matrix expression
+     *
+     * For a \f$(m\times n)\f$-dimensional matrix, the \c banded_adaptor will provide a banded matrix
+     * with \f$l\f$ lower and \f$u\f$ upper diagonals and \f$0 \leq i < m\f$ and \f$0 \leq j < n\f$,
+     * if \f$i>j+l\f$ or \f$i<j-u\f$ then \f$b_{i,j}=0\f$. 
+     *
+     * Storage and location are based on those of the underlying matrix. This is important because
+     * a \c banded_adaptor does not copy the matrix data to a new place. Therefore, modifying values
+     * in a \c banded_adaptor matrix will also modify the underlying matrix too.
+     *
+     * \tparam M the type of matrix used to generate a banded matrix
+     */
+    template<class M>
+    class banded_adaptor:
+        public matrix_expression<banded_adaptor<M> > {
+
+        typedef banded_adaptor<M> self_type;
+
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef const M const_matrix_type;
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        // Replaced by _temporary_traits to avoid type requirements on M
+        //typedef typename M::vector_temporary_type vector_temporary_type;
+        //typedef typename M::matrix_temporary_type matrix_temporary_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 packed_proxy_tag>::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        banded_adaptor (matrix_type &data, size_type lower = 0, size_type upper = 0):
+            matrix_expression<self_type> (),
+            data_ (data), lower_ (lower), upper_ (upper) {}
+        BOOST_UBLAS_INLINE
+        banded_adaptor (const banded_adaptor &m):
+            matrix_expression<self_type> (),
+            data_ (m.data_), lower_ (m.lower_), upper_ (m.upper_) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return data_.size1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return data_.size2 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type lower () const {
+            return lower_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type upper () const {
+            return upper_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+#if !defined (BOOST_UBLAS_OWN_BANDED)||(BOOST_UBLAS_LEGACY_BANDED)
+        BOOST_UBLAS_INLINE
+        bool is_element_in_band(size_type i, size_type j) const{
+            //return (upper_+i >= j) && i <= std::min(size1() - 1, j + lower_); // We don't need to check if i is outside because it is checked anyway in the accessors.
+            return (upper_+i >= j) && i <= ( j + lower_); // Essentially this band has "infinite" positive dimensions
+        }
+#endif
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+#ifdef BOOST_UBLAS_OWN_BANDED
+            size_type k = (std::max) (i, j);
+            size_type l = lower_ + j - i;
+            if (k < (std::max) (size1 (), size2 ()) &&
+                l < lower_ + 1 + upper_)
+                return data () (i, j);
+#elif BOOST_UBLAS_LEGACY_BANDED
+            size_type k = j;
+            size_type l = upper_ + i - j;
+            if (k < size2 () &&
+                l < lower_ + 1 + upper_)
+                return data () (i, j);
+#else
+            if (is_element_in_band( i, j))
+                return data () (i, j);
+#endif
+            return zero_;
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+#ifdef BOOST_UBLAS_OWN_BANDED
+            size_type k = (std::max) (i, j);
+            size_type l = lower_ + j - i;
+            if (k < (std::max) (size1 (), size2 ()) &&
+                l < lower_ + 1 + upper_)
+                return data () (i, j);
+#elif BOOST_UBLAS_LEGACY_BANDED
+            size_type k = j;
+            size_type l = upper_ + i - j;
+            if (k < size2 () &&
+                l < lower_ + 1 + upper_)
+                return data () (i, j);
+#else
+            if (is_element_in_band( i, j))
+                return data () (i, j);
+#endif
+#ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
+            bad_index ().raise ();
+#endif
+            return const_cast<reference>(zero_);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+#ifdef BOOST_UBLAS_OWN_BANDED
+            size_type k = (std::max) (i, j);
+            size_type l = lower_ + j - i;
+            if (k < (std::max) (size1 (), size2 ()) &&
+                l < lower_ + 1 + upper_)
+                return data () (i, j);
+#elif BOOST_UBLAS_LEGACY_BANDED
+            size_type k = j;
+            size_type l = upper_ + i - j;
+            if (k < size2 () &&
+                l < lower_ + 1 + upper_)
+                return data () (i, j);
+#else
+            if (is_element_in_band( i, j))
+                return data () (i, j);
+#endif
+#ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
+            bad_index ().raise ();
+#endif
+            return const_cast<reference>(zero_);
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        banded_adaptor &operator = (const banded_adaptor &m) {
+            matrix_assign<scalar_assign> (*this, m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        banded_adaptor &assign_temporary (banded_adaptor &m) {
+            *this = m;
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_adaptor &operator = (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, matrix<value_type> (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_adaptor &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_adaptor& operator += (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_adaptor &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_adaptor& operator -= (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        banded_adaptor &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        banded_adaptor& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        banded_adaptor& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const banded_adaptor &ba) const {
+            return (*this).data ().same_closure (ba.data ());
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (banded_adaptor &m) {
+            if (this != &m) {
+                BOOST_UBLAS_CHECK (lower_ == m.lower_, bad_size ());
+                BOOST_UBLAS_CHECK (upper_ == m.upper_, bad_size ());
+                matrix_swap<scalar_swap> (*this, m);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (banded_adaptor &m1, banded_adaptor &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use the matrix iterator
+        typedef typename M::const_iterator1 const_subiterator1_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator1,
+                                          typename M::iterator1>::type subiterator1_type;
+        typedef typename M::const_iterator2 const_subiterator2_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator2,
+                                          typename M::iterator2>::type subiterator2_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            if (rank == 1) {
+                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
+                i = (std::max) (i, lower_i);
+                size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
+                i = (std::min) (i, upper_i);
+            }
+            return const_iterator1 (*this, data ().find1 (rank, i, j));
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int rank, size_type i, size_type j) {
+            if (rank == 1) {
+                size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
+                i = (std::max) (i, lower_i);
+                size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
+                i = (std::min) (i, upper_i);
+            }
+            return iterator1 (*this, data ().find1 (rank, i, j));
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            if (rank == 1) {
+                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
+                j = (std::max) (j, lower_j);
+                size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
+                j = (std::min) (j, upper_j);
+            }
+            return const_iterator2 (*this, data ().find2 (rank, i, j));
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int rank, size_type i, size_type j) {
+            if (rank == 1) {
+                size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
+                j = (std::max) (j, lower_j);
+                size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
+                j = (std::min) (j, upper_j);
+            }
+            return iterator2 (*this, data ().find2 (rank, i, j));
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<banded_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename const_subiterator1_type::value_type value_type;
+            typedef typename const_subiterator1_type::difference_type difference_type;
+            typedef typename const_subiterator1_type::reference reference;
+            typedef typename const_subiterator1_type::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, const const_subiterator1_type &it1):
+                container_const_reference<self_type> (m), it1_ (it1) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                size_type i = index1 ();
+                size_type j = index2 ();
+                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
+#ifdef BOOST_UBLAS_OWN_BANDED
+                size_type k = (std::max) (i, j);
+                size_type l = (*this) ().lower () + j - i;
+                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
+                    l < (*this) ().lower () + 1 + (*this) ().upper ())
+                    return *it1_;
+#else
+                size_type k = j;
+                size_type l = (*this) ().upper () + i - j;
+                if (k < (*this) ().size2 () &&
+                    l < (*this) ().lower () + 1 + (*this) ().upper ())
+                    return *it1_;
+#endif
+                return (*this) () (i, j);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it1_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<banded_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               iterator1, value_type> {
+        public:
+            typedef typename subiterator1_type::value_type value_type;
+            typedef typename subiterator1_type::difference_type difference_type;
+            typedef typename subiterator1_type::reference reference;
+            typedef typename subiterator1_type::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it1_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, const subiterator1_type &it1):
+                container_reference<self_type> (m), it1_ (it1) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                size_type i = index1 ();
+                size_type j = index2 ();
+                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
+#ifdef BOOST_UBLAS_OWN_BANDED
+                size_type k = (std::max) (i, j);
+                size_type l = (*this) ().lower () + j - i;
+                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
+                    l < (*this) ().lower () + 1 + (*this) ().upper ())
+                    return *it1_;
+#else
+                size_type k = j;
+                size_type l = (*this) ().upper () + i - j;
+                if (k < (*this) ().size2 () &&
+                    l < (*this) ().lower () + 1 + (*this) ().upper ())
+                    return *it1_;
+#endif
+                return (*this) () (i, j);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it1_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            subiterator1_type it1_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1 (), 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<banded_adaptor>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename iterator_restrict_traits<typename const_subiterator2_type::iterator_category,
+                                                      packed_random_access_iterator_tag>::iterator_category iterator_category;
+            typedef typename const_subiterator2_type::value_type value_type;
+            typedef typename const_subiterator2_type::difference_type difference_type;
+            typedef typename const_subiterator2_type::reference reference;
+            typedef typename const_subiterator2_type::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (m), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                size_type i = index1 ();
+                size_type j = index2 ();
+                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
+#ifdef BOOST_UBLAS_OWN_BANDED
+                size_type k = (std::max) (i, j);
+                size_type l = (*this) ().lower () + j - i;
+                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
+                    l < (*this) ().lower () + 1 + (*this) ().upper ())
+                    return *it2_;
+#else
+                size_type k = j;
+                size_type l = (*this) ().upper () + i - j;
+                if (k < (*this) ().size2 () &&
+                    l < (*this) ().lower () + 1 + (*this) ().upper ())
+                    return *it2_;
+#endif
+                return (*this) () (i, j);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it2_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<banded_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               iterator2, value_type> {
+        public:
+            typedef typename subiterator2_type::value_type value_type;
+            typedef typename subiterator2_type::difference_type difference_type;
+            typedef typename subiterator2_type::reference reference;
+            typedef typename subiterator2_type::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, const subiterator2_type &it2):
+                container_reference<self_type> (m), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                size_type i = index1 ();
+                size_type j = index2 ();
+                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
+#ifdef BOOST_UBLAS_OWN_BANDED
+                size_type k = (std::max) (i, j);
+                size_type l = (*this) ().lower () + j - i;
+                if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
+                    l < (*this) ().lower () + 1 + (*this) ().upper ())
+                    return *it2_;
+#else
+                size_type k = j;
+                size_type l = (*this) ().upper () + i - j;
+                if (k < (*this) ().size2 () &&
+                    l < (*this) ().lower () + 1 + (*this) ().upper ())
+                    return *it2_;
+#endif
+                return (*this) () (i, j);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it2_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            subiterator2_type it2_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2 ());
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        size_type lower_;
+        size_type upper_;
+        typedef const value_type const_value_type;
+        static const_value_type zero_;
+    };
+
+    // Specialization for temporary_traits
+    template <class M>
+    struct vector_temporary_traits< banded_adaptor<M> >
+    : vector_temporary_traits< M > {} ;
+    template <class M>
+    struct vector_temporary_traits< const banded_adaptor<M> >
+    : vector_temporary_traits< M > {} ;
+
+    template <class M>
+    struct matrix_temporary_traits< banded_adaptor<M> >
+    : matrix_temporary_traits< M > {} ;
+    template <class M>
+    struct matrix_temporary_traits< const banded_adaptor<M> >
+    : matrix_temporary_traits< M > {} ;
+
+
+    template<class M>
+    typename banded_adaptor<M>::const_value_type banded_adaptor<M>::zero_ = value_type/*zero*/();
+
+    /** \brief A diagonal matrix adaptator: convert a any matrix into a diagonal matrix expression
+     *
+     * For a \f$(m\times m)\f$-dimensional matrix, the \c diagonal_adaptor will provide a diagonal matrix
+     * with \f$0 \leq i < m\f$ and \f$0 \leq j < m\f$, if \f$i\neq j\f$ then \f$b_{i,j}=0\f$. 
+     *
+     * Storage and location are based on those of the underlying matrix. This is important because
+     * a \c diagonal_adaptor does not copy the matrix data to a new place. Therefore, modifying values
+     * in a \c diagonal_adaptor matrix will also modify the underlying matrix too.
+     *
+     * \tparam M the type of matrix used to generate the diagonal matrix
+     */
+
+    template<class M>
+    class diagonal_adaptor:
+        public banded_adaptor<M> {
+    public:
+        typedef M matrix_type;
+        typedef banded_adaptor<M> adaptor_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        diagonal_adaptor ():
+            adaptor_type () {}
+        BOOST_UBLAS_INLINE
+        diagonal_adaptor (matrix_type &data):
+            adaptor_type (data) {}
+        BOOST_UBLAS_INLINE
+        ~diagonal_adaptor () {}
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        diagonal_adaptor &operator = (const diagonal_adaptor &m) {
+            adaptor_type::operator = (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        diagonal_adaptor &operator = (const matrix_expression<AE> &ae) {
+            adaptor_type::operator = (ae);
+            return *this;
+        }
+    };
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/blas.hpp b/include/boost/numeric/ublas/blas.hpp
new file mode 100644
index 0000000..318760b
--- /dev/null
+++ b/include/boost/numeric/ublas/blas.hpp
@@ -0,0 +1,499 @@
+//  Copyright (c) 2000-2011 Joerg Walter, Mathias Koch, David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+
+#ifndef _BOOST_UBLAS_BLAS_
+#define _BOOST_UBLAS_BLAS_
+
+#include <boost/numeric/ublas/traits.hpp>
+
+namespace boost { namespace numeric { namespace ublas {
+    
+
+    /** Interface and implementation of BLAS level 1
+     * This includes functions which perform \b vector-vector operations.
+     * More information about BLAS can be found at 
+     * <a href="http://en.wikipedia.org/wiki/BLAS">http://en.wikipedia.org/wiki/BLAS</a>
+     */
+    namespace blas_1 {
+
+        /** 1-Norm: \f$\sum_i |x_i|\f$ (also called \f$\mathcal{L}_1\f$ or Manhattan norm)
+     *
+     * \param v a vector or vector expression
+     * \return the 1-Norm with type of the vector's type
+     *
+     * \tparam V type of the vector (not needed by default)
+     */
+        template<class V>
+        typename type_traits<typename V::value_type>::real_type
+        asum (const V &v) {
+            return norm_1 (v);
+        }
+
+        /** 2-Norm: \f$\sum_i |x_i|^2\f$ (also called \f$\mathcal{L}_2\f$ or Euclidean norm)
+     *
+     * \param v a vector or vector expression
+     * \return the 2-Norm with type of the vector's type
+     *
+     * \tparam V type of the vector (not needed by default)
+     */
+        template<class V>
+        typename type_traits<typename V::value_type>::real_type
+        nrm2 (const V &v) {
+            return norm_2 (v);
+        }
+
+        /** Infinite-norm: \f$\max_i |x_i|\f$ (also called \f$\mathcal{L}_\infty\f$ norm)
+     *
+     * \param v a vector or vector expression
+     * \return the Infinite-Norm with type of the vector's type
+     *
+     * \tparam V type of the vector (not needed by default)
+     */
+        template<class V>
+        typename type_traits<typename V::value_type>::real_type
+        amax (const V &v) {
+            return norm_inf (v);
+        }
+
+        /** Inner product of vectors \f$v_1\f$ and \f$v_2\f$
+     *
+     * \param v1 first vector of the inner product
+     * \param v2 second vector of the inner product
+     * \return the inner product of the type of the most generic type of the 2 vectors
+     *
+     * \tparam V1 type of first vector (not needed by default)
+     * \tparam V2 type of second vector (not needed by default)
+     */
+        template<class V1, class V2>
+        typename promote_traits<typename V1::value_type, typename V2::value_type>::promote_type
+        dot (const V1 &v1, const V2 &v2) {
+            return inner_prod (v1, v2);
+        }
+
+        /** Copy vector \f$v_2\f$ to \f$v_1\f$
+     *
+     * \param v1 target vector
+     * \param v2 source vector
+     * \return a reference to the target vector
+     *
+     * \tparam V1 type of first vector (not needed by default)
+     * \tparam V2 type of second vector (not needed by default)
+     */
+        template<class V1, class V2>
+        V1 & copy (V1 &v1, const V2 &v2) 
+    {
+            return v1.assign (v2);
+        }
+
+        /** Swap vectors \f$v_1\f$ and \f$v_2\f$
+     *
+     * \param v1 first vector
+     * \param v2 second vector
+     * 
+         * \tparam V1 type of first vector (not needed by default)
+     * \tparam V2 type of second vector (not needed by default)
+     */
+    template<class V1, class V2>
+        void swap (V1 &v1, V2 &v2) 
+    {
+            v1.swap (v2);
+        }
+
+        /** scale vector \f$v\f$ with scalar \f$t\f$ 
+     *
+     * \param v vector to be scaled
+     * \param t the scalar
+     * \return \c t*v
+     *
+     * \tparam V type of the vector (not needed by default)
+     * \tparam T type of the scalar (not needed by default)
+     */
+        template<class V, class T>
+        V & scal (V &v, const T &t) 
+    {
+            return v *= t;
+        }
+
+        /** Compute \f$v_1= v_1 +  t.v_2\f$
+     *
+     * \param v1 target and first vector
+     * \param t the scalar
+     * \param v2 second vector
+     * \return a reference to the first and target vector
+     *
+     * \tparam V1 type of the first vector (not needed by default)
+     * \tparam T type of the scalar (not needed by default)
+     * \tparam V2 type of the second vector (not needed by default)
+     */
+        template<class V1, class T, class V2>
+        V1 & axpy (V1 &v1, const T &t, const V2 &v2) 
+    {
+            return v1.plus_assign (t * v2);
+        }
+
+    /** Performs rotation of points in the plane and assign the result to the first vector
+     *
+     * Each point is defined as a pair \c v1(i) and \c v2(i), being respectively 
+     * the \f$x\f$ and \f$y\f$ coordinates. The parameters \c t1 and \t2 are respectively 
+     * the cosine and sine of the angle of the rotation.
+     * Results are not returned but directly written into \c v1.
+     *
+     * \param t1 cosine of the rotation
+     * \param v1 vector of \f$x\f$ values
+     * \param t2 sine of the rotation 
+     * \param v2 vector of \f$y\f$ values
+     *
+     * \tparam T1 type of the cosine value (not needed by default)
+     * \tparam V1 type of the \f$x\f$ vector (not needed by default)
+     * \tparam T2 type of the sine value (not needed by default)
+     * \tparam V2 type of the \f$y\f$ vector (not needed by default)
+     */
+        template<class T1, class V1, class T2, class V2>
+        void rot (const T1 &t1, V1 &v1, const T2 &t2, V2 &v2) 
+    {
+            typedef typename promote_traits<typename V1::value_type, typename V2::value_type>::promote_type promote_type;
+            vector<promote_type> vt (t1 * v1 + t2 * v2);
+            v2.assign (- t2 * v1 + t1 * v2);
+            v1.assign (vt);
+        }
+
+    }
+
+    /** \brief Interface and implementation of BLAS level 2
+     * This includes functions which perform \b matrix-vector operations.
+     * More information about BLAS can be found at
+     * <a href="http://en.wikipedia.org/wiki/BLAS">http://en.wikipedia.org/wiki/BLAS</a>
+     */
+    namespace blas_2 {
+
+       /** \brief multiply vector \c v with triangular matrix \c m
+    *
+    * \param v a vector
+    * \param m a triangular matrix
+    * \return the result of the product
+    *
+    * \tparam V type of the vector (not needed by default)
+    * \tparam M type of the matrix (not needed by default)
+        */                 
+        template<class V, class M>
+        V & tmv (V &v, const M &m) 
+    {
+            return v = prod (m, v);
+        }
+
+        /** \brief solve \f$m.x = v\f$ in place, where \c m is a triangular matrix
+     *
+     * \param v a vector
+     * \param m a matrix
+     * \param C (this parameter is not needed)
+     * \return a result vector from the above operation
+     *
+     * \tparam V type of the vector (not needed by default)
+     * \tparam M type of the matrix (not needed by default)
+     * \tparam C n/a
+         */                 
+        template<class V, class M, class C>
+        V & tsv (V &v, const M &m, C) 
+    {
+            return v = solve (m, v, C ());
+        }
+
+        /** \brief compute \f$ v_1 = t_1.v_1 + t_2.(m.v_2)\f$, a general matrix-vector product
+     *
+     * \param v1 a vector
+     * \param t1 a scalar
+     * \param t2 another scalar
+     * \param m a matrix
+     * \param v2 another vector
+     * \return the vector \c v1 with the result from the above operation
+     *
+     * \tparam V1 type of first vector (not needed by default)
+     * \tparam T1 type of first scalar (not needed by default)
+     * \tparam T2 type of second scalar (not needed by default)
+     * \tparam M type of matrix (not needed by default)
+     * \tparam V2 type of second vector (not needed by default)
+         */                 
+        template<class V1, class T1, class T2, class M, class V2>
+        V1 & gmv (V1 &v1, const T1 &t1, const T2 &t2, const M &m, const V2 &v2) 
+    {
+            return v1 = t1 * v1 + t2 * prod (m, v2);
+        }
+
+        /** \brief Rank 1 update: \f$ m = m + t.(v_1.v_2^T)\f$
+     *
+     * \param m a matrix
+     * \param t a scalar
+     * \param v1 a vector
+     * \param v2 another vector
+     * \return a matrix with the result from the above operation
+     *
+     * \tparam M type of matrix (not needed by default)
+     * \tparam T type of scalar (not needed by default)
+     * \tparam V1 type of first vector (not needed by default)
+     * \tparam V2type of second vector (not needed by default)
+     */
+        template<class M, class T, class V1, class V2>
+        M & gr (M &m, const T &t, const V1 &v1, const V2 &v2) 
+    {
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+            return m += t * outer_prod (v1, v2);
+#else
+            return m = m + t * outer_prod (v1, v2);
+#endif
+        }
+
+        /** \brief symmetric rank 1 update: \f$m = m + t.(v.v^T)\f$
+     *
+     * \param m a matrix
+     * \param t a scalar
+     * \param v a vector
+     * \return a matrix with the result from the above operation
+     *
+     * \tparam M type of matrix (not needed by default)
+     * \tparam T type of scalar (not needed by default)
+     * \tparam V type of vector (not needed by default)
+     */
+        template<class M, class T, class V>
+        M & sr (M &m, const T &t, const V &v) 
+    {
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+            return m += t * outer_prod (v, v);
+#else
+            return m = m + t * outer_prod (v, v);
+#endif
+        }
+
+        /** \brief hermitian rank 1 update: \f$m = m + t.(v.v^H)\f$
+     *
+     * \param m a matrix
+     * \param t a scalar
+     * \param v a vector
+     * \return a matrix with the result from the above operation
+     *
+     * \tparam M type of matrix (not needed by default)
+     * \tparam T type of scalar (not needed by default)
+     * \tparam V type of vector (not needed by default)
+     */
+        template<class M, class T, class V>
+        M & hr (M &m, const T &t, const V &v) 
+    {
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+            return m += t * outer_prod (v, conj (v));
+#else
+            return m = m + t * outer_prod (v, conj (v));
+#endif
+        }
+
+         /** \brief symmetric rank 2 update: \f$ m=m+ t.(v_1.v_2^T + v_2.v_1^T)\f$ 
+      *
+      * \param m a matrix
+      * \param t a scalar
+      * \param v1 a vector
+      * \param v2 another vector
+      * \return a matrix with the result from the above operation
+      *
+      * \tparam M type of matrix (not needed by default)
+      * \tparam T type of scalar (not needed by default)
+      * \tparam V1 type of first vector (not needed by default)
+      * \tparam V2type of second vector (not needed by default)
+          */                 
+        template<class M, class T, class V1, class V2>
+        M & sr2 (M &m, const T &t, const V1 &v1, const V2 &v2) 
+    {
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+            return m += t * (outer_prod (v1, v2) + outer_prod (v2, v1));
+#else
+            return m = m + t * (outer_prod (v1, v2) + outer_prod (v2, v1));
+#endif
+        }
+
+        /** \brief hermitian rank 2 update: \f$m=m+t.(v_1.v_2^H) + v_2.(t.v_1)^H)\f$ 
+     *
+     * \param m a matrix
+     * \param t a scalar
+     * \param v1 a vector
+     * \param v2 another vector
+     * \return a matrix with the result from the above operation
+     *
+     * \tparam M type of matrix (not needed by default)
+     * \tparam T type of scalar (not needed by default)
+     * \tparam V1 type of first vector (not needed by default)
+     * \tparam V2type of second vector (not needed by default)
+         */                 
+        template<class M, class T, class V1, class V2>
+        M & hr2 (M &m, const T &t, const V1 &v1, const V2 &v2) 
+    {
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+            return m += t * outer_prod (v1, conj (v2)) + type_traits<T>::conj (t) * outer_prod (v2, conj (v1));
+#else
+            return m = m + t * outer_prod (v1, conj (v2)) + type_traits<T>::conj (t) * outer_prod (v2, conj (v1));
+#endif
+        }
+
+    }
+
+    /** \brief Interface and implementation of BLAS level 3
+     * This includes functions which perform \b matrix-matrix operations.
+     * More information about BLAS can be found at 
+     * <a href="http://en.wikipedia.org/wiki/BLAS">http://en.wikipedia.org/wiki/BLAS</a>
+     */
+    namespace blas_3 {
+
+        /** \brief triangular matrix multiplication \f$m_1=t.m_2.m_3\f$ where \f$m_2\f$ and \f$m_3\f$ are triangular
+     *
+     * \param m1 a matrix for storing result
+     * \param t a scalar
+     * \param m2 a triangular matrix
+     * \param m3 a triangular matrix
+     * \return the matrix \c m1
+     *
+     * \tparam M1 type of the result matrix (not needed by default)
+     * \tparam T type of the scalar (not needed by default)
+     * \tparam M2 type of the first triangular matrix (not needed by default)
+     * \tparam M3 type of the second triangular matrix (not needed by default)
+     *
+        */                 
+        template<class M1, class T, class M2, class M3>
+        M1 & tmm (M1 &m1, const T &t, const M2 &m2, const M3 &m3) 
+    {
+            return m1 = t * prod (m2, m3);
+        }
+
+        /** \brief triangular solve \f$ m_2.x = t.m_1\f$ in place, \f$m_2\f$ is a triangular matrix
+     *
+     * \param m1 a matrix
+     * \param t a scalar
+     * \param m2 a triangular matrix
+     * \param C (not used)
+     * \return the \f$m_1\f$ matrix
+     *
+     * \tparam M1 type of the first matrix (not needed by default)
+     * \tparam T type of the scalar (not needed by default)
+     * \tparam M2 type of the triangular matrix (not needed by default)
+     * \tparam C (n/a)
+         */                 
+        template<class M1, class T, class M2, class C>
+        M1 & tsm (M1 &m1, const T &t, const M2 &m2, C) 
+    {
+            return m1 = solve (m2, t * m1, C ());
+        }
+
+        /** \brief general matrix multiplication \f$m_1=t_1.m_1 + t_2.m_2.m_3\f$
+     *
+     * \param m1 first matrix
+     * \param t1 first scalar
+     * \param t2 second scalar
+     * \param m2 second matrix
+     * \param m3 third matrix
+     * \return the matrix \c m1
+     *
+     * \tparam M1 type of the first matrix (not needed by default)
+     * \tparam T1 type of the first scalar (not needed by default)
+     * \tparam T2 type of the second scalar (not needed by default)
+     * \tparam M2 type of the second matrix (not needed by default)
+     * \tparam M3 type of the third matrix (not needed by default)
+         */                 
+        template<class M1, class T1, class T2, class M2, class M3>
+        M1 & gmm (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2, const M3 &m3) 
+    {
+            return m1 = t1 * m1 + t2 * prod (m2, m3);
+        }
+
+        /** \brief symmetric rank \a k update: \f$m_1=t.m_1+t_2.(m_2.m_2^T)\f$
+     *
+     * \param m1 first matrix
+     * \param t1 first scalar
+     * \param t2 second scalar
+     * \param m2 second matrix
+     * \return matrix \c m1
+     *
+     * \tparam M1 type of the first matrix (not needed by default)
+     * \tparam T1 type of the first scalar (not needed by default)
+     * \tparam T2 type of the second scalar (not needed by default)
+     * \tparam M2 type of the second matrix (not needed by default)
+     * \todo use opb_prod()
+         */                 
+        template<class M1, class T1, class T2, class M2>
+        M1 & srk (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2) 
+    {
+            return m1 = t1 * m1 + t2 * prod (m2, trans (m2));
+        }
+
+        /** \brief hermitian rank \a k update: \f$m_1=t.m_1+t_2.(m_2.m2^H)\f$
+     *
+     * \param m1 first matrix
+     * \param t1 first scalar
+     * \param t2 second scalar
+     * \param m2 second matrix
+     * \return matrix \c m1
+     *
+     * \tparam M1 type of the first matrix (not needed by default)
+     * \tparam T1 type of the first scalar (not needed by default)
+     * \tparam T2 type of the second scalar (not needed by default)
+     * \tparam M2 type of the second matrix (not needed by default)
+     * \todo use opb_prod()
+         */                 
+        template<class M1, class T1, class T2, class M2>
+        M1 & hrk (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2) 
+    {
+            return m1 = t1 * m1 + t2 * prod (m2, herm (m2));
+        }
+
+        /** \brief generalized symmetric rank \a k update: \f$m_1=t_1.m_1+t_2.(m_2.m3^T)+t_2.(m_3.m2^T)\f$
+     *
+     * \param m1 first matrix
+     * \param t1 first scalar
+     * \param t2 second scalar
+     * \param m2 second matrix
+     * \param m3 third matrix
+     * \return matrix \c m1
+     *
+     * \tparam M1 type of the first matrix (not needed by default)
+     * \tparam T1 type of the first scalar (not needed by default)
+     * \tparam T2 type of the second scalar (not needed by default)
+     * \tparam M2 type of the second matrix (not needed by default)
+     * \tparam M3 type of the third matrix (not needed by default)
+     * \todo use opb_prod()
+         */                 
+        template<class M1, class T1, class T2, class M2, class M3>
+        M1 & sr2k (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2, const M3 &m3) 
+    {
+            return m1 = t1 * m1 + t2 * (prod (m2, trans (m3)) + prod (m3, trans (m2)));
+        }
+
+        /** \brief generalized hermitian rank \a k update: * \f$m_1=t_1.m_1+t_2.(m_2.m_3^H)+(m_3.(t_2.m_2)^H)\f$
+     *
+     * \param m1 first matrix
+     * \param t1 first scalar
+     * \param t2 second scalar
+     * \param m2 second matrix
+     * \param m3 third matrix
+     * \return matrix \c m1
+     *
+     * \tparam M1 type of the first matrix (not needed by default)
+     * \tparam T1 type of the first scalar (not needed by default)
+     * \tparam T2 type of the second scalar (not needed by default)
+     * \tparam M2 type of the second matrix (not needed by default)
+     * \tparam M3 type of the third matrix (not needed by default)
+     * \todo use opb_prod()
+         */                 
+        template<class M1, class T1, class T2, class M2, class M3>
+        M1 & hr2k (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2, const M3 &m3) 
+    {
+            return m1 = 
+              t1 * m1 
+            + t2 * prod (m2, herm (m3)) 
+            + type_traits<T2>::conj (t2) * prod (m3, herm (m2));
+        }
+
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/detail/concepts.hpp b/include/boost/numeric/ublas/detail/concepts.hpp
new file mode 100644
index 0000000..674c610
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/concepts.hpp
@@ -0,0 +1,1575 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_CONCEPTS_
+#define _BOOST_UBLAS_CONCEPTS_
+
+#include <boost/concept_check.hpp>
+
+// Concept checks based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+
+
+    template<class I>
+    struct Indexed1DIteratorConcept {
+        typedef I iterator_type;
+
+        void constraints () {
+            iterator_type it = iterator_type ();
+            // Index
+            it.index ();
+        }
+    };
+
+    template<class I>
+    struct IndexedBidirectional1DIteratorConcept {
+        typedef I iterator_type;
+
+        void constraints () {
+            function_requires< BidirectionalIteratorConcept<iterator_type> >();
+            function_requires< Indexed1DIteratorConcept<iterator_type> >();
+        }
+    };
+
+    template<class I>
+    struct Mutable_IndexedBidirectional1DIteratorConcept {
+        typedef I iterator_type;
+
+        void constraints () {
+            function_requires< Mutable_BidirectionalIteratorConcept<iterator_type> >();
+            function_requires< Indexed1DIteratorConcept<iterator_type> >();
+        }
+    };
+
+    template<class I>
+    struct IndexedRandomAccess1DIteratorConcept {
+        typedef I iterator_type;
+
+        void constraints () {
+            function_requires< RandomAccessIteratorConcept<iterator_type> >();
+            function_requires< Indexed1DIteratorConcept<iterator_type> >();
+        }
+    };
+
+    template<class I>
+    struct Mutable_IndexedRandomAccess1DIteratorConcept {
+        typedef I iterator_type;
+
+        void constraints () {
+            function_requires< Mutable_RandomAccessIteratorConcept<iterator_type> >();
+            function_requires< Indexed1DIteratorConcept<iterator_type> >();
+        }
+    };
+
+    template<class I>
+    struct Indexed2DIteratorConcept {
+        typedef I iterator_type;
+        typedef typename I::dual_iterator_type dual_iterator_type;
+        typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
+
+        void constraints () {
+            iterator_type it = iterator_type ();
+            // Indices
+            it.index1 ();
+            it.index2 ();
+            // Iterator begin/end
+            dual_iterator_type it_begin (it.begin ());
+            dual_iterator_type it_end (it.end ());
+            // Reverse iterator begin/end
+            dual_reverse_iterator_type it_rbegin (it.rbegin ());
+            dual_reverse_iterator_type it_rend (it.rend ());
+            ignore_unused_variable_warning (it_begin);
+            ignore_unused_variable_warning (it_end);
+            ignore_unused_variable_warning (it_rbegin);
+            ignore_unused_variable_warning (it_rend);
+        }
+    };
+
+    template<class I1, class I2>
+    struct IndexedBidirectional2DIteratorConcept {
+        typedef I1 subiterator1_type;
+        typedef I2 subiterator2_type;
+
+        void constraints () {
+            function_requires< BidirectionalIteratorConcept<subiterator1_type> >();
+            function_requires< BidirectionalIteratorConcept<subiterator2_type> >();
+            function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
+            function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
+        }
+    };
+
+    template<class I1, class I2>
+    struct Mutable_IndexedBidirectional2DIteratorConcept {
+        typedef I1 subiterator1_type;
+        typedef I2 subiterator2_type;
+
+        void constraints () {
+            function_requires< Mutable_BidirectionalIteratorConcept<subiterator1_type> >();
+            function_requires< Mutable_BidirectionalIteratorConcept<subiterator2_type> >();
+            function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
+            function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
+        }
+    };
+
+    template<class I1, class I2>
+    struct IndexedRandomAccess2DIteratorConcept {
+        typedef I1 subiterator1_type;
+        typedef I2 subiterator2_type;
+
+        void constraints () {
+            function_requires< RandomAccessIteratorConcept<subiterator1_type> >();
+            function_requires< RandomAccessIteratorConcept<subiterator2_type> >();
+            function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
+            function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
+        }
+    };
+
+    template<class I1, class I2>
+    struct Mutable_IndexedRandomAccess2DIteratorConcept {
+        typedef I1 subiterator1_type;
+        typedef I2 subiterator2_type;
+
+        void constraints () {
+            function_requires< Mutable_RandomAccessIteratorConcept<subiterator1_type> >();
+            function_requires< Mutable_RandomAccessIteratorConcept<subiterator2_type> >();
+            function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
+            function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
+        }
+    };
+
+    template<class C>
+    struct StorageArrayConcept {
+        typedef C container_type;
+        typedef typename C::size_type size_type;
+        typedef typename C::value_type value_type;
+
+        void constraints () {
+            function_requires< RandomAccessContainerConcept<container_type> >();
+            size_type n (0);
+            // Sizing constructor
+            container_type c = container_type (n);
+            // Initialised sizing constructor
+            container_type (n, value_type (5));
+            ignore_unused_variable_warning (c);
+        }
+    };
+
+    template<class C>
+    struct Mutable_StorageArrayConcept {
+        typedef C container_type;
+        typedef typename C::size_type size_type;
+        typedef typename C::value_type value_type;
+        typedef typename C::iterator iterator_type;
+
+        void constraints () {
+            function_requires< Mutable_RandomAccessContainerConcept<container_type> > ();
+            size_type n (0);
+            // Sizing constructor
+            container_type c = container_type (n);
+            // Initialised sizing constructor
+            c = container_type (n, value_type (3));
+            // Resize
+            c.resize (n, value_type (5));
+            // Resize - none preserving
+            c.resize (n);
+        }
+    };
+
+    template<class C>
+    struct StorageSparseConcept {
+        typedef C container_type;
+        typedef typename C::size_type size_type;
+
+        void constraints () {
+            function_requires< ReversibleContainerConcept<container_type> > ();
+        }
+    };
+
+    template<class C>
+    struct Mutable_StorageSparseConcept {
+        typedef C container_type;
+        typedef typename C::size_type size_type;
+        typedef typename C::value_type value_type;
+        typedef typename C::iterator iterator_type;
+
+        void constraints () {
+            // NOTE - Not Mutable_ReversibleContainerConcept
+            function_requires< ReversibleContainerConcept<container_type> >();
+            container_type c = container_type ();
+            value_type t = value_type ();
+            iterator_type it = iterator_type (), it1 = iterator_type (), it2 = iterator_type ();
+            // Insert
+            c.insert (it, t);
+            // Erase
+            c.erase (it);
+            // Range erase
+            c.erase (it1, it2);
+            // Clear
+            c.clear ();
+        }
+    };
+
+    template<class G>
+    struct IndexSetConcept {
+        typedef G generator_type;
+        typedef typename G::size_type size_type;
+        typedef typename G::value_type value_type;
+
+        void constraints () {
+            function_requires< AssignableConcept<generator_type> >();
+            function_requires< ReversibleContainerConcept<generator_type> >();
+            generator_type g = generator_type ();
+            size_type n (0);
+            value_type t;
+            // Element access
+            t = g (n);
+            ignore_unused_variable_warning (t);
+        }
+    };
+
+    /** \brief Scalar expression concept.
+     *
+     * requirements
+     * \li \c SE::value_type is the type of the scalar expression
+     * \li \c SE must be convertable to \c SE::value_type
+     * \li the constant \c SE::complexity must exist
+     *
+     * \param SE the type of the scalar expression
+     */
+    template<class SE>
+    struct ScalarExpressionConcept {
+        typedef SE scalar_expression_type;
+        typedef typename SE::value_type value_type;
+
+        static const unsigned complexity = SE::complexity;
+
+        void constraints () {
+            scalar_expression_type *sp;
+            scalar_expression_type s = *sp;
+            value_type t;
+            // Conversion
+            t = s;
+            ignore_unused_variable_warning (t);
+        }
+    };
+
+    /** \brief Vector expression concept.
+     *
+     * requirements
+     * \li \c VE::value_type is the type of the elements
+     * \li \c VE::const_reference The return type when accessing an element of a constant vector 
+     * expression. Must be convertable to a \c value_type.
+     * \li \c VE::size_type is the (unsigned) type of the indices
+     * \li \c VE::difference_type is the (signed) type of distances between indices
+     * \li \c VE::category
+     * 
+     * \li the constant \c SE::complexity must exist
+     *
+     * \param SE the type of the scalar expression
+     */
+    template<class VE>
+    struct VectorExpressionConcept {
+        typedef VE vector_expression_type;
+        typedef typename VE::type_category type_category;
+        typedef typename VE::size_type size_type;
+        typedef typename VE::difference_type difference_type;
+        typedef typename VE::value_type value_type;
+        typedef typename VE::const_reference const_reference;
+        typedef typename VE::const_iterator const_iterator_type;
+        typedef typename VE::const_reverse_iterator const_reverse_iterator_type;
+
+        void constraints () {
+            vector_expression_type *vp;
+            const vector_expression_type *cvp;
+            vector_expression_type v = *vp;
+            const vector_expression_type cv = *cvp;
+            size_type n (0), i (0);
+            value_type t;
+            // Find (internal?)
+            const_iterator_type cit (v.find (i));
+            // Beginning of range
+            const_iterator_type cit_begin (v.begin ());
+            // End of range
+            const_iterator_type cit_end (v.end ());
+            // Size
+            n = v.size ();
+            // Beginning of reverse range
+            const_reverse_iterator_type crit_begin (cv.rbegin ());
+            // End of reverse range
+            const_reverse_iterator_type crit_end (cv.rend ());
+            // Element access
+            t = v (i);
+            ignore_unused_variable_warning (n);
+            ignore_unused_variable_warning (cit);
+            ignore_unused_variable_warning (cit_begin);
+            ignore_unused_variable_warning (cit_end);
+            ignore_unused_variable_warning (crit_begin);
+            ignore_unused_variable_warning (crit_end);
+            ignore_unused_variable_warning (t);
+        }
+    };
+
+    template<class VE>
+    struct Mutable_VectorExpressionConcept {
+        typedef VE vector_expression_type;
+        typedef typename VE::size_type size_type;
+        typedef typename VE::value_type value_type;
+        typedef typename VE::iterator iterator_type;
+        typedef typename VE::reverse_iterator reverse_iterator_type;
+
+        void constraints () {
+            function_requires< AssignableConcept<vector_expression_type> >();
+            function_requires< VectorExpressionConcept<vector_expression_type> >();
+            vector_expression_type *vp;
+            vector_expression_type v = *vp, v1 = *vp, v2 = *vp;
+            size_type i (0);
+            value_type t = value_type ();
+            // Find (internal?)
+            iterator_type it (v.find (i));
+            // Beginning of range
+            iterator_type it_begin (v.begin ());
+            // End of range
+            iterator_type it_end (v.end ());
+            // Swap
+            v1.swap (v2);
+            // Beginning of reverse range
+            reverse_iterator_type rit_begin (v.rbegin ());
+            // End of reverse range
+            reverse_iterator_type rit_end (v.rend ());
+            // Assignments
+            v2 = v1;
+            v2.assign (v1);
+            v2 += v1;
+            v2.plus_assign (v1);
+            v2 -= v1;
+            v2.minus_assign (v1);
+            v *= t;
+            ignore_unused_variable_warning (it);
+            ignore_unused_variable_warning (it_begin);
+            ignore_unused_variable_warning (it_end);
+            ignore_unused_variable_warning (rit_begin);
+            ignore_unused_variable_warning (rit_end);
+        }
+    };
+
+    template<class ME>
+    struct MatrixExpressionConcept {
+        typedef ME matrix_expression_type;
+        typedef typename ME::type_category type_category;
+        typedef typename ME::size_type size_type;
+        typedef typename ME::value_type value_type;
+        typedef typename ME::const_iterator1 const_subiterator1_type;
+        typedef typename ME::const_iterator2 const_subiterator2_type;
+        typedef typename ME::const_reverse_iterator1 const_reverse_subiterator1_type;
+        typedef typename ME::const_reverse_iterator2 const_reverse_subiterator2_type;
+
+        void constraints () {
+            matrix_expression_type *mp;
+            const matrix_expression_type *cmp;
+            matrix_expression_type m = *mp;
+            const matrix_expression_type cm = *cmp;
+            size_type n (0), i (0), j (0);
+            value_type t;
+            // Find (internal?)
+            const_subiterator1_type cit1 (m.find1 (0, i, j));
+            const_subiterator2_type cit2 (m.find2 (0, i, j));
+            // Beginning of range
+            const_subiterator1_type cit1_begin (m.begin1 ());
+            const_subiterator2_type cit2_begin (m.begin2 ());
+            // End of range
+            const_subiterator1_type cit1_end (m.end1 ());
+            const_subiterator2_type cit2_end (m.end2 ());
+            // Size
+            n = m.size1 ();
+            n = m.size2 ();
+            // Beginning of reverse range
+            const_reverse_subiterator1_type crit1_begin (cm.rbegin1 ());
+            const_reverse_subiterator2_type crit2_begin (cm.rbegin2 ());
+            // End of reverse range
+            const_reverse_subiterator1_type crit1_end (cm.rend1 ());
+            const_reverse_subiterator2_type crit2_end (cm.rend2 ());
+            // Element access
+            t = m (i, j);
+            ignore_unused_variable_warning (n);
+            ignore_unused_variable_warning (cit1);
+            ignore_unused_variable_warning (cit2);
+            ignore_unused_variable_warning (cit1_begin);
+            ignore_unused_variable_warning (cit2_begin);
+            ignore_unused_variable_warning (cit1_end);
+            ignore_unused_variable_warning (cit2_end);
+            ignore_unused_variable_warning (crit1_begin);
+            ignore_unused_variable_warning (crit2_begin);
+            ignore_unused_variable_warning (crit1_end);
+            ignore_unused_variable_warning (crit2_end);
+            ignore_unused_variable_warning (t);
+        }
+    };
+
+    template<class ME>
+    struct Mutable_MatrixExpressionConcept {
+        typedef ME matrix_expression_type;
+        typedef typename ME::size_type size_type;
+        typedef typename ME::value_type value_type;
+        typedef typename ME::iterator1 subiterator1_type;
+        typedef typename ME::iterator2 subiterator2_type;
+        typedef typename ME::reverse_iterator1 reverse_subiterator1_type;
+        typedef typename ME::reverse_iterator2 reverse_subiterator2_type;
+
+        void constraints () {
+            function_requires< AssignableConcept<matrix_expression_type> >();
+            function_requires< MatrixExpressionConcept<matrix_expression_type> >();
+            matrix_expression_type *mp;
+            matrix_expression_type m = *mp, m1 = *mp, m2 = *mp;
+            size_type i (0), j (0);
+            value_type t = value_type ();
+            // Find (internal?)
+            subiterator1_type it1 (m.find1 (0, i, j));
+            subiterator2_type it2 (m.find2 (0, i, j));
+            // Beginning of range
+            subiterator1_type it1_begin (m.begin1 ());
+            subiterator2_type it2_begin (m.begin2 ());
+            // End of range
+            subiterator1_type it1_end (m.end1 ());
+            subiterator2_type it2_end (m.end2 ());
+            // Swap
+            m1.swap (m2);
+            // Beginning of reverse range
+            reverse_subiterator1_type rit1_begin (m.rbegin1 ());
+            reverse_subiterator2_type rit2_begin (m.rbegin2 ());
+            // End of reverse range
+            reverse_subiterator1_type rit1_end (m.rend1 ());
+            reverse_subiterator2_type rit2_end (m.rend2 ());
+            // Assignments
+            m2 = m1;
+            m2.assign (m1);
+            m2 += m1;
+            m2.plus_assign (m1);
+            m2 -= m1;
+            m2.minus_assign (m1);
+            m *= t;
+            ignore_unused_variable_warning (it1);
+            ignore_unused_variable_warning (it2);
+            ignore_unused_variable_warning (it1_begin);
+            ignore_unused_variable_warning (it2_begin);
+            ignore_unused_variable_warning (it1_end);
+            ignore_unused_variable_warning (it2_end);
+            ignore_unused_variable_warning (rit1_begin);
+            ignore_unused_variable_warning (rit2_begin);
+            ignore_unused_variable_warning (rit1_end);
+            ignore_unused_variable_warning (rit2_end);
+        }
+    };
+
+    template<class V>
+    struct VectorConcept {
+        typedef V vector_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::value_type value_type;
+        typedef const value_type *const_pointer;
+
+        void constraints () {
+            function_requires< VectorExpressionConcept<vector_type> >();
+            size_type n (0);
+            size_type i (0);
+            // Sizing constructor
+            vector_type v (n);
+            // Element support
+            const_pointer p = v.find_element (i);
+
+            ignore_unused_variable_warning (p);
+        }
+    };
+
+    template<class V>
+    struct Mutable_VectorConcept {
+        typedef V vector_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::value_type value_type;
+        typedef value_type *pointer;
+
+        void constraints () {
+            function_requires< VectorConcept<vector_type> >();
+            function_requires< DefaultConstructible<vector_type> >();
+            function_requires< Mutable_VectorExpressionConcept<vector_type> >();
+            size_type n (0);
+            value_type t = value_type ();
+            size_type i (0);
+            vector_type v;
+            // Element support
+            pointer p = v.find_element (i);
+            // Element assignment
+            value_type r = v.insert_element (i, t);
+            v.insert_element (i, t) = r;
+            // Zeroing
+            v.clear ();
+            // Resize
+            v.resize (n);
+
+            ignore_unused_variable_warning (p);
+            ignore_unused_variable_warning (r);
+        }
+    };
+
+    template<class V>
+    struct SparseVectorConcept {
+        typedef V vector_type;
+        typedef typename V::size_type size_type;
+
+        void constraints () {
+            function_requires< VectorConcept<vector_type> >();
+        }
+    };
+
+    template<class V>
+    struct Mutable_SparseVectorConcept {
+        typedef V vector_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::value_type value_type;
+
+        void constraints () {
+            function_requires< SparseVectorConcept<vector_type> >();
+            function_requires< Mutable_VectorConcept<vector_type> >();
+            size_type i (0);
+            vector_type v;
+            // Element erasure
+            v.erase_element (i);
+        }
+    };
+
+    template<class M>
+    struct MatrixConcept {
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+        typedef const value_type *const_pointer;
+
+        void constraints () {
+            function_requires< MatrixExpressionConcept<matrix_type> >();
+            size_type n (0);
+            size_type i (0), j (0);
+            // Sizing constructor
+            matrix_type m (n, n);
+            // Element support
+#ifndef SKIP_BAD
+            const_pointer p = m.find_element (i, j);
+#else
+            const_pointer p;
+            ignore_unused_variable_warning (i);
+            ignore_unused_variable_warning (j);
+#endif
+            ignore_unused_variable_warning (p);
+        }
+    };
+
+    template<class M>
+    struct Mutable_MatrixConcept {
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+        typedef value_type *pointer;
+
+        void constraints () {
+            function_requires< MatrixConcept<matrix_type> >();
+            function_requires< DefaultConstructible<matrix_type> >();
+            function_requires< Mutable_MatrixExpressionConcept<matrix_type> >();
+            size_type n (0);
+            value_type t = value_type ();
+            size_type i (0), j (0);
+            matrix_type m;
+            // Element support
+#ifndef SKIP_BAD
+            pointer p = m.find_element (i, j);
+            ignore_unused_variable_warning (i);
+            ignore_unused_variable_warning (j);
+#else
+            pointer p;
+#endif
+            // Element assigment
+            value_type r = m.insert_element (i, j, t);
+            m.insert_element (i, j, t) = r;
+            // Zeroing
+            m.clear ();
+            // Resize
+            m.resize (n, n);
+            m.resize (n, n, false);
+
+            ignore_unused_variable_warning (p);
+            ignore_unused_variable_warning (r);
+        }
+    };
+
+    template<class M>
+    struct SparseMatrixConcept {
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+
+        void constraints () {
+            function_requires< MatrixConcept<matrix_type> >();
+        }
+    };
+
+    template<class M>
+    struct Mutable_SparseMatrixConcept {
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+
+        void constraints () {
+            function_requires< SparseMatrixConcept<matrix_type> >();
+            function_requires< Mutable_MatrixConcept<matrix_type> >();
+            size_type i (0), j (0);
+            matrix_type m;
+            // Elemnent erasure
+            m.erase_element (i, j);
+        }
+    };
+
+    /** introduce anonymous namespace to make following functions
+     * local to the current compilation unit.
+     */
+    namespace {
+
+    // Replaced the ZeroElement and OneElement functions with the templated versions
+    // because the former where giving warnings with clang
+    template<class T>
+    T
+    ZeroElement (T) {
+        return T(0.0);
+    }
+
+    template<class T>
+    vector<T>
+    ZeroElement (vector<T>) {
+        return zero_vector<T> ();
+    }
+
+    template<class T>
+    matrix<T>
+    ZeroElement (matrix<T>) {
+        return zero_matrix<T> ();
+    }
+
+    template<class T>
+    T
+    OneElement (T) {
+        return T(0.0);
+    }
+
+    template<class T>
+    vector<T>
+    OneElement (vector<T>) {
+        return zero_vector<T> ();
+    }
+
+    template<class T>
+    matrix<T>
+    OneElement (matrix<T>) {
+        return identity_matrix<T> ();
+    }
+
+//    template<>
+//    float
+//    ZeroElement (float) {
+//        return 0.f;
+//    }
+//    template<>
+//    double
+//    ZeroElement (double) {
+//        return 0.;
+//    }
+//    template<>
+//    vector<float>
+//    ZeroElement (vector<float>) {
+//        return zero_vector<float> ();
+//    }
+//    template<>
+//    vector<double>
+//    ZeroElement (vector<double>) {
+//        return zero_vector<double> ();
+//    }
+//    template<>
+//    matrix<float>
+//    ZeroElement (matrix<float>) {
+//        return zero_matrix<float> ();
+//    }
+//    template<>
+//    matrix<double>
+//    ZeroElement (matrix<double>) {
+//        return zero_matrix<double> ();
+//    }
+//    template<>
+//    std::complex<float>
+//    ZeroElement (std::complex<float>) {
+//        return std::complex<float> (0.f);
+//    }
+//    template<>
+//    std::complex<double>
+//    ZeroElement (std::complex<double>) {
+//        return std::complex<double> (0.);
+//    }
+//    template<>
+//    vector<std::complex<float> >
+//    ZeroElement (vector<std::complex<float> >) {
+//        return zero_vector<std::complex<float> > ();
+//    }
+//    template<>
+//    vector<std::complex<double> >
+//    ZeroElement (vector<std::complex<double> >) {
+//        return zero_vector<std::complex<double> > ();
+//    }
+//    template<>
+//    matrix<std::complex<float> >
+//    ZeroElement (matrix<std::complex<float> >) {
+//        return zero_matrix<std::complex<float> > ();
+//    }
+//    template<>
+//    matrix<std::complex<double> >
+//    ZeroElement (matrix<std::complex<double> >) {
+//        return zero_matrix<std::complex<double> > ();
+//    }
+
+//    template<class T>
+//    T
+//    OneElement (T);
+//    template<>
+//    float
+//    OneElement (float) {
+//        return 1.f;
+//    }
+//    template<>
+//    double
+//    OneElement (double) {
+//        return 1.;
+//    }
+//    template<>
+//    matrix<float>
+//    OneElement (matrix<float>) {
+//        return identity_matrix<float> ();
+//    }
+//    template<>
+//    matrix<double>
+//    OneElement (matrix<double>) {
+//        return identity_matrix<double> ();
+//    }
+//    template<>
+//    std::complex<float>
+//    OneElement (std::complex<float>) {
+//        return std::complex<float> (1.f);
+//    }
+//    template<>
+//    std::complex<double>
+//    OneElement (std::complex<double>) {
+//        return std::complex<double> (1.);
+//    }
+//    template<>
+//    matrix<std::complex<float> >
+//    OneElement (matrix<std::complex<float> >) {
+//        return identity_matrix<std::complex<float> > ();
+//    }
+//    template<>
+//    matrix<std::complex<double> >
+//    OneElement (matrix<std::complex<double> >) {
+//        return identity_matrix<std::complex<double> > ();
+//    }
+
+    template<class E1, class E2>
+    bool
+    operator == (const vector_expression<E1> &e1, const vector_expression<E2> &e2) {
+        typedef typename promote_traits<typename E1::value_type,
+                                                    typename E2::value_type>::promote_type value_type;
+        typedef typename type_traits<value_type>::real_type real_type;
+        return norm_inf (e1 - e2) == real_type/*zero*/();
+    }
+    template<class E1, class E2>
+    bool
+    operator == (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
+        typedef typename promote_traits<typename E1::value_type,
+                                                    typename E2::value_type>::promote_type value_type;
+        typedef typename type_traits<value_type>::real_type real_type;
+        return norm_inf (e1 - e2) == real_type/*zero*/();
+    }
+
+    template<class T>
+    struct AdditiveAbelianGroupConcept {
+        typedef T value_type;
+
+        void constraints () {
+            bool r;
+            value_type a = value_type (), b = value_type (), c = value_type ();
+            r = (a + b) + c == a + (b + c);
+            r = ZeroElement (value_type ()) + a == a;
+            r = a + ZeroElement (value_type ()) == a;
+            r = a + (- a) == ZeroElement (value_type ());
+            r = (- a) + a == ZeroElement (value_type ());
+            r = a + b == b + a;
+            ignore_unused_variable_warning (r);
+        }
+    };
+
+    template<class T>
+    struct MultiplicativeAbelianGroupConcept {
+        typedef T value_type;
+
+        void constraints () {
+            bool r;
+            value_type a = value_type (), b = value_type (), c = value_type ();
+            r = (a * b) * c == a * (b * c);
+            r = OneElement (value_type ()) * a == a;
+            r = a * OneElement (value_type ()) == a;
+            r = a * (OneElement (value_type ()) / a) == a;
+            r = (OneElement (value_type ()) / a) * a == a;
+            r = a * b == b * a;
+            ignore_unused_variable_warning (r);
+        }
+    };
+
+    template<class T>
+    struct RingWithIdentityConcept {
+        typedef T value_type;
+
+        void constraints () {
+            function_requires< AdditiveAbelianGroupConcept<value_type> >();
+            bool r;
+            value_type a = value_type (), b = value_type (), c = value_type ();
+            r = (a * b) * c == a * (b * c);
+            r = (a + b) * c == a * c + b * c;
+            r = OneElement (value_type ()) * a == a;
+            r = a * OneElement (value_type ()) == a;
+            ignore_unused_variable_warning (r);
+        }
+    };
+
+    template<class T>
+    struct Prod_RingWithIdentityConcept {
+        typedef T value_type;
+
+        void constraints () {
+            function_requires< AdditiveAbelianGroupConcept<value_type> >();
+            bool r;
+            value_type a = value_type (), b = value_type (), c = value_type ();
+            r = prod (T (prod (a, b)), c) == prod (a, T (prod (b, c)));
+            r = prod (a + b, c) == prod (a, c) + prod (b, c);
+            r = prod (OneElement (value_type ()), a) == a;
+            r = prod (a, OneElement (value_type ())) == a;
+            ignore_unused_variable_warning (r);
+        }
+    };
+
+    template<class T>
+    struct CommutativeRingWithIdentityConcept {
+        typedef T value_type;
+
+        void constraints () {
+            function_requires< RingWithIdentityConcept<value_type> >();
+            bool r;
+            value_type a = value_type (), b = value_type ();
+            r = a * b == b * a;
+            ignore_unused_variable_warning (r);
+        }
+    };
+
+    template<class T>
+    struct FieldConcept {
+        typedef T value_type;
+
+        void constraints () {
+            function_requires< CommutativeRingWithIdentityConcept<value_type> >();
+            bool r;
+            value_type a = value_type ();
+            r = a == ZeroElement (value_type ()) || a * (OneElement (value_type ()) / a) == a;
+            r = a == ZeroElement (value_type ()) || (OneElement (value_type ()) / a) * a == a;
+            ignore_unused_variable_warning (r);
+        }
+    };
+
+    template<class T, class V>
+    struct VectorSpaceConcept {
+        typedef T value_type;
+        typedef V vector_type;
+
+        void constraints () {
+            function_requires< FieldConcept<value_type> >();
+            function_requires< AdditiveAbelianGroupConcept<vector_type> >();
+            bool r;
+            value_type alpha = value_type (), beta = value_type ();
+            vector_type a = vector_type (), b = vector_type ();
+            r = alpha * (a + b) == alpha * a + alpha * b;
+            r = (alpha + beta) * a == alpha * a + beta * a;
+            r = (alpha * beta) * a == alpha * (beta * a);
+            r = OneElement (value_type ()) * a == a;
+            ignore_unused_variable_warning (r);
+        }
+    };
+
+    template<class T, class V, class M>
+    struct LinearOperatorConcept {
+        typedef T value_type;
+        typedef V vector_type;
+        typedef M matrix_type;
+
+        void constraints () {
+            function_requires< VectorSpaceConcept<value_type, vector_type> >();
+            bool r;
+            value_type alpha = value_type (), beta = value_type ();
+            vector_type a = vector_type (), b = vector_type ();
+            matrix_type A = matrix_type ();
+            r = prod (A, alpha * a + beta * b) == alpha * prod (A, a) + beta * prod (A, b);
+            ignore_unused_variable_warning (r);
+        }
+    };
+
+inline void concept_checks () {
+
+        // Allow tests to be group to keep down compiler storage requirement
+#ifdef INTERAL
+#define INTERNAL_STORAGE
+#define INTERNAL_VECTOR
+#define INTERNAL_MATRIX
+#define INTERNAL_SPECIAL
+#define INTERNAL_SPARSE
+#define INTERNAL_EXPRESSION
+#endif
+
+        // TODO enable this for development
+        // #define VIEW_CONCEPTS
+
+        // Element value type for tests
+        typedef float T;
+
+        // Storage Array
+#if defined (INTERNAL_STORAGE) || defined (INTERNAL_STORAGE_DENSE)
+        {
+            typedef std::vector<T> container_model;
+            function_requires< Mutable_StorageArrayConcept<container_model> >();
+            function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
+        }
+
+        {
+            typedef bounded_array<T, 1> container_model;
+            function_requires< Mutable_StorageArrayConcept<container_model> >();
+            function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
+        }
+
+        {
+            typedef unbounded_array<T> container_model;
+            function_requires< Mutable_StorageArrayConcept<container_model> >();
+            function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
+        }
+
+/* FIXME array_adaptors are in progress
+        {
+            typedef array_adaptor<T> container_model;
+            function_requires< Mutable_StorageArrayConcept<container_model> >();
+            function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
+        }
+*/
+
+        {
+            typedef range container_model;
+            function_requires< IndexSetConcept<range> >();
+            function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
+        }
+
+        {
+            typedef slice container_model;
+            function_requires< IndexSetConcept<range> >();
+            function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
+        }
+
+        {
+            typedef indirect_array<> container_model;
+            function_requires< IndexSetConcept<range> >();
+            function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
+        }
+#endif
+
+        // Storage Sparse
+#if defined (INTERNAL_STORAGE) || defined (INTERNAL_STORAGE_SPARSE)
+        {
+           typedef map_array<std::size_t, T> container_model;
+           function_requires< Mutable_StorageSparseConcept<container_model> >();
+           function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
+           function_requires< RandomAccessIteratorConcept<container_model::iterator> >();
+        }
+
+        {
+           typedef std::map<std::size_t, T> container_model;
+           function_requires< Mutable_StorageSparseConcept<container_model > >();
+           function_requires< BidirectionalIteratorConcept<container_model::const_iterator> >();
+           function_requires< BidirectionalIteratorConcept<container_model::iterator> >();
+        }
+#endif
+
+#ifdef VIEW_CONCEPTS
+        // read only vectors
+        {
+           typedef vector_view<T> container_model;
+           function_requires< RandomAccessContainerConcept<container_model> >();
+           function_requires< VectorConcept<container_model> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+        }
+#endif
+
+        // Vector
+#if defined (INTERNAL_VECTOR) || defined (INTERNAL_VECTOR_DENSE)
+        {
+           typedef vector<T> container_model;
+           function_requires< RandomAccessContainerConcept<container_model> >();
+           function_requires< Mutable_VectorConcept<container_model> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+           function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+           function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+
+        {
+           typedef zero_vector<T> container_model;
+           function_requires< VectorConcept<container_model> >();
+           function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
+           function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
+        }
+
+        {
+           typedef unit_vector<T> container_model;
+           function_requires< VectorConcept<container_model> >();
+           function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
+           function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
+        }
+
+        {
+           typedef scalar_vector<T> container_model;
+           function_requires< VectorConcept<container_model> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+        }
+
+        {
+           typedef c_vector<T, 1> container_model;
+           function_requires< Mutable_VectorConcept<container_model> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+           function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+           function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+#endif
+
+        // Vector Proxies
+#if defined (INTERNAL_VECTOR) || defined (INTERNAL_VECTOR_PROXY)
+        {
+           typedef vector_range<vector<T> > container_model;
+           function_requires< Mutable_VectorExpressionConcept<container_model> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+           function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+           function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+
+        {
+           typedef vector_slice<vector<T> > container_model;
+           function_requires< Mutable_VectorExpressionConcept<container_model> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+           function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+           function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+
+        {
+           typedef vector_indirect<vector<T> > container_model;
+           function_requires< Mutable_VectorExpressionConcept<container_model> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+           function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
+           function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+           function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+#endif
+
+        // Sparse Vector
+#if defined (INTERNAL_SPARSE) || defined (INTERNAL_VECTOR_SPARSE)
+        {
+            typedef mapped_vector<T> container_model;
+            function_requires< Mutable_SparseVectorConcept<container_model> >();
+            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
+            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
+            function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+
+        {
+            typedef compressed_vector<T> container_model;
+            function_requires< Mutable_SparseVectorConcept<container_model> >();
+            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
+            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
+            function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+
+        {
+            typedef coordinate_vector<T> container_model;
+            function_requires< Mutable_SparseVectorConcept<container_model> >();
+            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
+            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
+            function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+#endif
+
+        // Matrix
+#if defined (INTERNAL_MATRIX) || defined (INTERNAL_MATRIX_DENSE)
+        {
+            typedef matrix<T> container_model;
+            function_requires< Mutable_MatrixConcept<matrix<T> > >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+
+        {
+            typedef vector_of_vector<T> container_model;
+            function_requires< Mutable_MatrixConcept<matrix<T> > >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+
+        {
+            typedef zero_matrix<T> container_model;
+            function_requires< Mutable_MatrixConcept<matrix<T> > >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef identity_matrix<T> container_model;
+            function_requires< Mutable_MatrixConcept<matrix<T> > >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef scalar_matrix<T> container_model;
+            function_requires< Mutable_MatrixConcept<matrix<T> > >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef c_matrix<T, 1, 1> container_model;
+            function_requires< Mutable_MatrixConcept<matrix<T> > >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+#endif
+
+        // Matrix Proxies
+#if defined (INTERNAL_MATRIX) || defined (INTERNAL_MATRIX_PROXY)
+        {
+            typedef matrix_row<matrix<T> > container_model;
+            function_requires< Mutable_VectorExpressionConcept<container_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+
+        {
+            typedef matrix_column<matrix<T> > container_model;
+            function_requires< Mutable_VectorExpressionConcept<container_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+
+        {
+            typedef matrix_vector_range<matrix<T> > container_model;
+            function_requires< Mutable_VectorExpressionConcept<container_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+
+        {
+            typedef matrix_vector_slice<matrix<T> > container_model;
+            function_requires< Mutable_VectorExpressionConcept<container_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+
+        {
+            typedef matrix_vector_indirect<matrix<T> > container_model;
+            function_requires< Mutable_VectorExpressionConcept<container_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
+        }
+
+        {
+            typedef matrix_range<matrix<T> > container_model;
+            function_requires< Mutable_MatrixExpressionConcept<container_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+
+        {
+            typedef matrix_slice<matrix<T> > container_model;
+            function_requires< Mutable_MatrixExpressionConcept<container_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+
+        {
+            typedef matrix_indirect<matrix<T> > container_model;
+            function_requires< Mutable_MatrixExpressionConcept<container_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+#endif
+
+        // Banded Matrix
+#if defined (INTERNAL_SPECIAL) || defined (INTERNAL_BANDED)
+        {
+            typedef banded_matrix<T> container_model;
+            function_requires< Mutable_MatrixConcept<container_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+
+        {
+            typedef banded_adaptor<matrix<T> > container_model;
+            function_requires< Mutable_MatrixExpressionConcept<container_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+#endif
+
+        // Triangular Matrix
+#if defined (INTERNAL_SPECIAL) || defined (INTERNAL_TRIANGULAR)
+        {
+            typedef triangular_matrix<T> container_model;
+            function_requires< Mutable_MatrixConcept<container_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+
+        {
+            typedef triangular_adaptor<matrix<T> > container_model;
+            function_requires< Mutable_MatrixExpressionConcept<container_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+#endif
+
+        // Symmetric Matrix
+#if defined (INTERNA_SPECIAL) || defined (INTERNAL_SYMMETRIC)
+        {
+            typedef symmetric_matrix<T> container_model;
+            function_requires< Mutable_MatrixConcept<container_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+
+        {
+            typedef banded_adaptor<matrix<T> > container_model;
+#ifndef SKIP_BAD
+           // const_iterator (iterator) constructor is bad
+            function_requires< Mutable_MatrixExpressionConcept<container_model> >();
+#endif
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+#endif
+
+        // Hermitian Matrix
+#if defined (INTERNAL_SPECIAL) || defined (INTERNAL_HERMITIAN)
+        {
+            typedef hermitian_matrix<T> container_model;
+            function_requires< Mutable_MatrixConcept<container_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+        
+        {
+            typedef hermitian_adaptor<matrix<T> > container_model;
+#ifndef SKIP_BAD
+           // const_iterator (iterator) constructor is bad
+            function_requires< Mutable_MatrixExpressionConcept<container_model> >();
+#endif
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+#endif
+
+        // Sparse Matrix
+#if defined (INTERNAL_SPARSE) || defined (INTERNAL_MATRIX_SPARSE)
+        {
+            typedef mapped_matrix<T> container_model;
+            function_requires< Mutable_SparseMatrixConcept<container_model> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+        {
+            typedef mapped_vector_of_mapped_vector<T> container_model;
+            function_requires< Mutable_SparseMatrixConcept<container_model> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+        {
+            typedef compressed_matrix<T> container_model;
+            function_requires< Mutable_SparseMatrixConcept<container_model> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+        {
+            typedef coordinate_matrix<T> container_model;
+            function_requires< Mutable_SparseMatrixConcept<container_model> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+        {
+            typedef generalized_vector_of_vector<T, row_major, vector< coordinate_vector<T> > > container_model;
+            function_requires< Mutable_SparseMatrixConcept<container_model> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
+            function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
+            function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
+        }
+
+#endif
+
+        // Scalar Expressions
+#if defined (INTERNAL_EXPRESSION) || defined (INTERNAL_VECTOR_EXPRESSION)
+        function_requires< ScalarExpressionConcept<scalar_value<T> > >();
+        function_requires< ScalarExpressionConcept<scalar_reference<T> > >();
+
+        // Vector Expressions
+        {
+            typedef vector_reference<vector<T> > expression_model;
+            function_requires< VectorExpressionConcept<expression_model> >();
+            function_requires< Mutable_VectorExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<expression_model::iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
+            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<expression_model::reverse_iterator> >();
+        }
+
+        {
+            typedef vector_unary<vector<T>, scalar_identity<T> > expression_model;
+            function_requires< VectorExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
+        }
+
+        {
+            typedef vector_binary<vector<T>, vector<T>, scalar_plus<T, T> > expression_model;
+            function_requires< VectorExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
+        }
+
+        {
+            typedef vector_binary_scalar1<T, vector<T>, scalar_multiplies<T, T> > expression_model;
+            function_requires< VectorExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
+        }
+
+        {
+            typedef vector_binary_scalar2<vector<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
+            function_requires< VectorExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
+        }
+
+        {
+            typedef vector_binary_scalar1<scalar_value<T>, vector<T>, scalar_multiplies<T, T> > expression_model;
+            function_requires< VectorExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
+        }
+
+        {
+            typedef vector_binary_scalar2<vector<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
+            function_requires< VectorExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
+        }
+
+        function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_sum<vector<T> > > > >();
+        function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_1<vector<T> > > > >();
+        function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_2<vector<T> > > > >();
+        function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_inf<vector<T> > > > >();
+
+        function_requires< ScalarExpressionConcept<vector_scalar_binary<vector<T>, vector<T>, vector_inner_prod<vector<T>, vector<T>, T> > > >();
+#endif
+
+        // Matrix Expressions
+#if defined (INTERNAL_EXPRESSION) || defined (INTERNAL_MATRIX_EXPRESSION)
+        {
+            typedef matrix_reference<matrix<T> > expression_model;
+            function_requires< MatrixExpressionConcept<expression_model> >();
+            function_requires< Mutable_MatrixExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<expression_model::iterator1, expression_model::iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
+            function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<expression_model::reverse_iterator1, expression_model::reverse_iterator2> >();
+        }
+
+        {
+            typedef vector_matrix_binary<vector<T>, vector<T>, scalar_multiplies<T, T> > expression_model;
+            function_requires< MatrixExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef matrix_unary1<matrix<T>, scalar_identity<T> > expression_model;
+            function_requires< MatrixExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef matrix_unary2<matrix<T>, scalar_identity<T> > expression_model;
+            function_requires< MatrixExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef matrix_binary<matrix<T>, matrix<T>, scalar_plus<T, T> > expression_model;
+            function_requires< MatrixExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef matrix_binary_scalar1<T, matrix<T>, scalar_multiplies<T, T> > expression_model;
+            function_requires< MatrixExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef matrix_binary_scalar2<matrix<T>, T, scalar_multiplies<T, T> > expression_model;
+            function_requires< MatrixExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef matrix_binary_scalar1<scalar_value<T>, matrix<T>, scalar_multiplies<T, T> > expression_model;
+            function_requires< MatrixExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef matrix_binary_scalar2<matrix<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
+            function_requires< MatrixExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
+        }
+
+        {
+            typedef matrix_vector_binary1<matrix<T>, vector<T>, matrix_vector_prod1<matrix<T>, vector<T>, T> > expression_model;
+            function_requires< VectorExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
+        }
+
+        {
+            typedef matrix_vector_binary2<vector<T>, matrix<T>, matrix_vector_prod2<matrix<T>, vector<T>, T > > expression_model;
+            function_requires< VectorExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
+            function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
+        }
+
+        {
+            typedef matrix_matrix_binary<matrix<T>, matrix<T>, matrix_matrix_prod<matrix<T>, matrix<T>, T > > expression_model;
+            function_requires< MatrixExpressionConcept<expression_model> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
+            function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
+        }
+
+        function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_1<vector<T> > > > >();
+        function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_frobenius<vector<T> > > > >();
+        function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_inf<vector<T> > > > >();
+#endif
+
+#ifdef EXTERNAL
+        function_requires< AdditiveAbelianGroupConcept<T> >();
+        function_requires< CommutativeRingWithIdentityConcept<T> >();
+        function_requires< FieldConcept<T> >();
+        function_requires< VectorSpaceConcept<T, vector<T> > >();
+        function_requires< Prod_RingWithIdentityConcept<matrix<T> > >();
+        function_requires< VectorSpaceConcept<T, matrix<T> > >();
+        function_requires< LinearOperatorConcept<T, vector<T>, matrix<T> > >();
+
+        function_requires< AdditiveAbelianGroupConcept<std::complex<T> > >();
+        function_requires< CommutativeRingWithIdentityConcept<std::complex<T> > >();
+        function_requires< FieldConcept<std::complex<T> > >();
+        function_requires< VectorSpaceConcept<std::complex<T>, vector<std::complex<T> > > >();
+        function_requires< Prod_RingWithIdentityConcept<matrix<std::complex<T> > > >();
+        function_requires< VectorSpaceConcept<std::complex<T>, matrix<std::complex<T> > > >();
+        function_requires< LinearOperatorConcept<std::complex<T>, vector<std::complex<T> >, matrix<std::complex<T> > > >();
+#endif
+    }
+
+    } // end of anonymous namespace
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/detail/config.hpp b/include/boost/numeric/ublas/detail/config.hpp
new file mode 100644
index 0000000..9e67410
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/config.hpp
@@ -0,0 +1,304 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_CONFIG_
+#define _BOOST_UBLAS_CONFIG_
+
+#include <cassert>
+#include <cstddef>
+#include <algorithm>
+#include <limits>
+
+#include <boost/config.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+// C++11
+#if defined(__cplusplus) && __cplusplus >= 201103L
+
+#define BOOST_UBLAS_CPP_GE_2011
+
+#elif BOOST_MSVC >= 1800
+
+#define BOOST_UBLAS_CPP_GE_2011
+
+#else
+
+#undef BOOST_UBLAS_CPP_GE_2011 // Make sure no one defined it
+
+#endif
+
+// Microsoft Visual C++
+#if defined (BOOST_MSVC) && ! defined (BOOST_STRICT_CONFIG)
+
+// Version 7.1
+#if BOOST_MSVC == 1310
+// One of these workarounds is needed for MSVC 7.1 AFAIK
+// (thanks to John Maddock and Martin Lauer).
+#if !(defined(BOOST_UBLAS_NO_NESTED_CLASS_RELATION) || defined(BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION))
+#define BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+#endif
+
+#endif
+
+#endif
+
+
+// GNU Compiler Collection
+#if defined (__GNUC__) && ! defined (BOOST_STRICT_CONFIG)
+
+#if __GNUC__ >= 4 || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4)
+// Specified by ABI definition see GCC bug id 9982
+#define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
+#endif
+
+#if __GNUC__ < 3
+#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
+#endif
+
+#endif
+
+
+// Intel Compiler
+#if defined (BOOST_INTEL) && ! defined (BOOST_STRICT_CONFIG)
+
+#if defined (BOOST_INTEL_LINUX) && (BOOST_INTEL_LINUX >= 800)
+// By inspection of compiler results
+#define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
+#endif
+
+#if (BOOST_INTEL < 700)
+#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
+#endif
+
+// Define swap for index_pair and triple.
+#if (BOOST_INTEL <= 800)
+namespace boost { namespace numeric { namespace ublas {
+    template<class C, class IC>
+    class indexed_iterator;
+
+    template<class V>
+    class index_pair;
+    template<class M>
+    class index_triple;
+}}}
+
+namespace std {
+    template<class V>
+    inline
+    void swap (boost::numeric::ublas::index_pair<V> i1, boost::numeric::ublas::index_pair<V> i2) {
+        i1.swap (i2);
+    }
+    template<class M>
+    inline
+    void swap (boost::numeric::ublas::index_triple<M> i1, boost::numeric::ublas::index_triple<M> i2) {
+        i1.swap (i2);
+    }
+    // iter_swap also needed for ICC on Itanium?
+    template<class C, class IC>
+    inline
+    void iter_swap (boost::numeric::ublas::indexed_iterator<C, IC> it1,
+                    boost::numeric::ublas::indexed_iterator<C, IC> it2) {
+        swap (*it1, *it2);
+    }
+}
+#endif
+
+#endif
+
+
+// Comeau compiler - thanks to Kresimir Fresl
+#if defined (__COMO__) && ! defined (BOOST_STRICT_CONFIG)
+
+// Missing std::abs overloads for float types in <cmath> are in <cstdlib>
+#if defined(__LIBCOMO__) && (__LIBCOMO_VERSION__ <= 31)
+#include <cstdlib>
+#endif
+
+#endif
+
+// PGI compiler
+#ifdef __PGIC__
+#define BOOST_UBLAS_UNSUPPORTED_COMPILER 0
+#endif
+
+//  HP aCC C++ compiler
+#if defined (__HP_aCC) && ! defined (BOOST_STRICT_CONFIG)
+#  if (__HP_aCC >= 60000 )
+#    define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
+#endif
+#endif
+
+
+//  SGI MIPSpro C++ compiler
+#if defined (__sgi) && ! defined (BOOST_STRICT_CONFIG)
+
+// Missing std::abs overloads for float types in <cmath> are in <cstdlib>
+// This test should be library version specific.
+#include <cstdlib>
+
+#if __COMPILER_VERSION >=650
+// By inspection of compiler results - thanks to Peter Schmitteckert
+#define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
+#endif
+
+#endif
+
+
+// Metrowerks Codewarrior
+#if defined (__MWERKS__) && ! defined (BOOST_STRICT_CONFIG)
+
+// 8.x
+#if __MWERKS__ <= 0x3003
+#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
+#endif
+
+#endif
+
+
+// Detect other compilers with serious defects - override by defineing BOOST_UBLAS_UNSUPPORTED_COMPILER=0
+#ifndef BOOST_UBLAS_UNSUPPORTED_COMPILER
+#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || defined(BOOST_NO_SFINAE) || defined(BOOST_NO_STDC_NAMESPACE)
+#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
+#endif
+#endif
+
+// Cannot continue with an unsupported compiler
+#if defined(BOOST_UBLAS_UNSUPPORTED_COMPILER) && (BOOST_UBLAS_UNSUPPORTED_COMPILER != 0)
+#error Your compiler and/or configuration is unsupported by this verions of uBLAS. Define BOOST_UBLAS_UNSUPPORTED_COMPILER=0 to override this message. Boost 1.32.0 includes uBLAS with support for many older compilers.
+#endif
+
+
+
+// Enable performance options in RELEASE mode
+#if defined (NDEBUG) || defined (BOOST_UBLAS_NDEBUG)
+
+#ifndef BOOST_UBLAS_INLINE
+#define BOOST_UBLAS_INLINE inline
+#endif
+
+// Do not check sizes!
+#define BOOST_UBLAS_USE_FAST_SAME
+
+// NO runtime error checks with BOOST_UBLAS_CHECK macro
+#ifndef BOOST_UBLAS_CHECK_ENABLE
+#define BOOST_UBLAS_CHECK_ENABLE 0
+#endif
+
+// NO type compatibility numeric checks
+#ifndef BOOST_UBLAS_TYPE_CHECK
+#define BOOST_UBLAS_TYPE_CHECK 0
+#endif
+
+
+// Disable performance options in DEBUG mode
+#else
+
+#ifndef BOOST_UBLAS_INLINE
+#define BOOST_UBLAS_INLINE
+#endif
+
+// Enable runtime error checks with BOOST_UBLAS_CHECK macro. Check bounds etc
+#ifndef BOOST_UBLAS_CHECK_ENABLE
+#define BOOST_UBLAS_CHECK_ENABLE 1
+#endif
+
+// Type compatibiltity numeric checks
+#ifndef BOOST_UBLAS_TYPE_CHECK
+#define BOOST_UBLAS_TYPE_CHECK 1
+#endif
+
+#endif
+
+
+/*
+ * Type compatibility checks
+ *  Control type compatibility numeric runtime checks for non dense matrices.
+ *  Require additional storage and complexity
+ */
+#if BOOST_UBLAS_TYPE_CHECK
+template <class Dummy>
+struct disable_type_check
+{
+    static bool value;
+};
+template <class Dummy>
+bool disable_type_check<Dummy>::value = false;
+#endif
+#ifndef BOOST_UBLAS_TYPE_CHECK_EPSILON
+#define BOOST_UBLAS_TYPE_CHECK_EPSILON (type_traits<real_type>::type_sqrt (std::numeric_limits<real_type>::epsilon ()))
+#endif
+#ifndef BOOST_UBLAS_TYPE_CHECK_MIN
+#define BOOST_UBLAS_TYPE_CHECK_MIN (type_traits<real_type>::type_sqrt ( (std::numeric_limits<real_type>::min) ()))
+#endif
+
+
+/*
+ * General Configuration
+ */
+
+// Proxy shortcuts overload the alreadly heavily over used operator ()
+//#define BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+
+// In order to simplify debugging is is possible to simplify expression template
+// so they are restricted to a single operation
+// #define BOOST_UBLAS_SIMPLE_ET_DEBUG
+
+// Use invariant hoisting.
+// #define BOOST_UBLAS_USE_INVARIANT_HOISTING
+
+// Use Duff's device in element access loops
+// #define BOOST_UBLAS_USE_DUFF_DEVICE
+
+// Choose evaluation method for dense vectors and matrices
+#if !(defined(BOOST_UBLAS_USE_INDEXING) || defined(BOOST_UBLAS_USE_ITERATING))
+#define BOOST_UBLAS_USE_INDEXING
+#endif
+// #define BOOST_UBLAS_ITERATOR_THRESHOLD 0
+
+// Use indexed iterators - unsupported implementation experiment
+// #define BOOST_UBLAS_USE_INDEXED_ITERATOR
+
+// Alignment of bounded_array type
+#ifndef BOOST_UBLAS_BOUNDED_ARRAY_ALIGN
+#define BOOST_UBLAS_BOUNDED_ARRAY_ALIGN
+#endif
+
+// Enable different sparse element proxies
+#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
+// Sparse proxies prevent reference invalidation problems in expressions such as:
+// a [1] = a [0] = 1        Thanks to Marc Duflot for spotting this.
+// #define BOOST_UBLAS_STRICT_MAP_ARRAY
+#define BOOST_UBLAS_STRICT_VECTOR_SPARSE
+#define BOOST_UBLAS_STRICT_MATRIX_SPARSE
+// Hermitian matrices use element proxies to allow assignment to conjugate triangle
+#define BOOST_UBLAS_STRICT_HERMITIAN
+#endif
+
+// Define to configure special settings for reference returning members
+// #define BOOST_UBLAS_REFERENCE_CONST_MEMBER
+// #define BOOST_UBLAS_PROXY_CONST_MEMBER
+
+
+// Include type declerations and functions
+#include <boost/numeric/ublas/fwd.hpp>
+#include <boost/numeric/ublas/detail/definitions.hpp>
+
+
+#endif
+
diff --git a/include/boost/numeric/ublas/detail/definitions.hpp b/include/boost/numeric/ublas/detail/definitions.hpp
new file mode 100644
index 0000000..c5e1cfc
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/definitions.hpp
@@ -0,0 +1,212 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_DEFINITIONS_
+#define _BOOST_UBLAS_DEFINITIONS_
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    namespace detail {
+        /* Borrowed from boost/concept_checks.hpp
+           "inline" is used for ignore_unused_variable_warning()
+           to make sure there is no overhead with g++.
+         */
+        template <class T> inline
+        void ignore_unused_variable_warning(const T&) {}
+    } // namespace detail
+
+    // Borrowed from Dave Abraham's noncopyable.
+    // I believe this should be part of utility.hpp one day...
+    namespace nonassignable_  // protection from unintended ADL
+    {
+        class nonassignable {
+        protected:
+            nonassignable () {}
+            ~nonassignable () {}
+        private:  // emphasize the following members are private
+            const nonassignable& operator= (const nonassignable &);
+        }; // nonassignable
+    }
+    typedef nonassignable_::nonassignable nonassignable;
+
+
+    // Assignment proxy.
+    // Provides temporary free assigment when LHS has no alias on RHS
+    template<class C>
+    class noalias_proxy:
+        private nonassignable {
+    public:
+        typedef typename C::closure_type closure_type;
+
+        BOOST_UBLAS_INLINE
+        noalias_proxy (C& lval):
+            nonassignable (), lval_ (lval) {}
+        BOOST_UBLAS_INLINE
+        noalias_proxy (const noalias_proxy& p):
+            nonassignable (), lval_ (p.lval_) {}
+
+        template <class E>
+        BOOST_UBLAS_INLINE
+        closure_type &operator= (const E& e) {
+            lval_.assign (e);
+            return lval_;
+        }
+
+        template <class E>
+        BOOST_UBLAS_INLINE
+        closure_type &operator+= (const E& e) {
+            lval_.plus_assign (e);
+            return lval_;
+        }
+
+        template <class E>
+        BOOST_UBLAS_INLINE
+        closure_type &operator-= (const E& e) {
+            lval_.minus_assign (e);
+            return lval_;
+        }
+
+    private:
+        closure_type lval_;
+    };
+
+    // Improve syntax of efficient assignment where no aliases of LHS appear on the RHS
+    //  noalias(lhs) = rhs_expression
+    template <class C>
+    BOOST_UBLAS_INLINE
+    noalias_proxy<C> noalias (C& lvalue) {
+        return noalias_proxy<C> (lvalue);
+    }
+    template <class C>
+    BOOST_UBLAS_INLINE
+    noalias_proxy<const C> noalias (const C& lvalue) {
+        return noalias_proxy<const C> (lvalue);
+    }
+
+    // Possible future compatible syntax where lvalue possible has an unsafe alias on the RHS
+    //  safe(lhs) = rhs_expression
+    template <class C>
+    BOOST_UBLAS_INLINE
+    C& safe (C& lvalue) {
+        return lvalue;
+    }
+    template <class C>
+    BOOST_UBLAS_INLINE
+    const C& safe (const C& lvalue) {
+        return lvalue;
+    }
+
+
+    // Dimension accessors
+    namespace dimension {
+
+        // Generic accessors
+        template<unsigned dimension>
+        struct dimension_properties {};
+        
+        template<>
+        struct dimension_properties<1> {
+            template <class E>
+            BOOST_UBLAS_INLINE static
+            typename E::size_type size (const vector_expression<E> &e) {
+                return e ().size ();
+            }
+            template <class E>
+            BOOST_UBLAS_INLINE static
+            typename E::size_type size (const matrix_expression<E> &e) {
+                return e ().size1 ();
+            }
+            // Note: Index functions cannot deduce dependant template parameter V or M from i
+            template <class V>
+            BOOST_UBLAS_INLINE static
+            typename V::size_type index (const typename V::iterator &i) {
+                return i.index ();
+            }
+            template <class M>
+            BOOST_UBLAS_INLINE static
+            typename M::size_type index (const typename M::iterator1 &i) {
+                return i.index1 ();
+            }
+            template <class M>
+            BOOST_UBLAS_INLINE static
+            typename M::size_type index (const typename M::iterator2 &i) {
+                return i.index1 ();
+            }
+        };
+        template<>
+        struct dimension_properties<2> {
+            template <class E>
+            BOOST_UBLAS_INLINE static
+            typename E::size_type size (const vector_expression<E> &) {
+                return 1;
+            }
+            template <class E>
+            BOOST_UBLAS_INLINE static
+            typename E::size_type size (const matrix_expression<E> &e) {
+                return e ().size2 ();
+            }
+            template <class V>
+            BOOST_UBLAS_INLINE static
+            typename V::size_type index (const typename V::iterator &) {
+                return 1;
+            }
+            template <class M>
+            BOOST_UBLAS_INLINE static
+            typename M::size_type index (const typename M::iterator1 &i) {
+                return i.index2 ();
+            }
+            template <class M>
+            BOOST_UBLAS_INLINE static
+            typename M::size_type index (const typename M::iterator2 &i) {
+                return i.index2 ();
+            }
+        };
+
+        template<unsigned dimension, class E>
+        BOOST_UBLAS_INLINE
+        typename E::size_type size (const E& e) {
+            return dimension_properties<dimension>::size (e);
+        }
+
+        template<unsigned dimension, class I>
+        BOOST_UBLAS_INLINE
+        typename I::container_type::size_type
+        index (const I& i) {
+            typedef typename I::container_type container_type;
+            return dimension_properties<dimension>::template index<container_type> (i);
+        }
+
+
+        // Named accessors - just syntactic sugar
+        template<class V>
+        typename V::size_type num_elements (const V &v) {
+            return v.size ();
+        }
+        template<class M>
+        typename M::size_type num_rows (const M &m) {
+            return m.size1 ();
+        }
+        template<class M>
+        typename M::size_type num_columns (const M &m) {
+            return m.size2 ();
+        }
+        template<class MV>
+        typename MV::size_type num_non_zeros (const MV &mv) {
+            return mv.non_zeros ();
+        }
+    }
+
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/detail/documentation.hpp b/include/boost/numeric/ublas/detail/documentation.hpp
new file mode 100644
index 0000000..4b2bcf0
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/documentation.hpp
@@ -0,0 +1,33 @@
+//
+//  Copyright (c) 2000-2004
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+// this file should not contain any code, but the documentation
+// global to all files
+
+/** \namespace boost::numeric::ublas
+        \brief contains all important classes and functions of uBLAS
+
+        all ublas definitions ...
+        \todo expand this section
+ */
+
+/** \defgroup blas1 Level 1 BLAS 
+        \brief level 1 basic linear algebra subroutines
+*/
+
+/** \defgroup blas2 Level 2 BLAS
+        \brief level 2 basic linear algebra subroutines 
+*/
+
+/** \defgroup blas3 Level 3 BLAS
+        \brief level 3 basic linear algebra subroutines 
+*/
diff --git a/include/boost/numeric/ublas/detail/duff.hpp b/include/boost/numeric/ublas/detail/duff.hpp
new file mode 100644
index 0000000..b0ec08c
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/duff.hpp
@@ -0,0 +1,56 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_DUFF_
+#define _BOOST_UBLAS_DUFF_
+
+#define DD_SWITCH(n, d, r, expr) \
+    { \
+        unsigned r = ((n) + (d) - 1) / (d); \
+        switch ((n) % (d))  { \
+        case 0: do { expr;
+#define DD_CASE_I(i, expr) \
+        case (i): expr;
+#define DD_WHILE(r) \
+            } while (-- (r) > 0); \
+        } \
+    }
+
+#define DD_1T(n, d, r, expr) \
+    DD_WHILE(r)
+#define DD_2T(n, d, r, expr) \
+    DD_CASE_I(1, expr) \
+    DD_1T(n, d, r, expr)
+#define DD_3T(n, d, r, expr) \
+    DD_CASE_I(2, expr) \
+    DD_2T(n, d, r, expr)
+#define DD_4T(n, d, r, expr) \
+    DD_CASE_I(3, expr) \
+    DD_3T(n, d, r, expr)
+#define DD_5T(n, d, r, expr) \
+    DD_CASE_I(4, expr) \
+    DD_4T(n, d, r, expr)
+#define DD_6T(n, d, r, expr) \
+    DD_CASE_I(5, expr) \
+    DD_5T(n, d, r, expr)
+#define DD_7T(n, d, r, expr) \
+    DD_CASE_I(6, expr) \
+    DD_6T(n, d, r, expr)
+#define DD_8T(n, d, r, expr) \
+    DD_CASE_I(7, expr) \
+    DD_7T(n, d, r, expr)
+
+#define DD(n, d, r, expr) \
+    DD_SWITCH(n, d, r, expr) \
+    DD_##d##T(n, d, r, expr)
+
+#endif
diff --git a/include/boost/numeric/ublas/detail/iterator.hpp b/include/boost/numeric/ublas/detail/iterator.hpp
new file mode 100644
index 0000000..1723a30
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/iterator.hpp
@@ -0,0 +1,1436 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_ITERATOR_
+#define _BOOST_UBLAS_ITERATOR_
+
+#include <boost/numeric/ublas/exception.hpp>
+#include <iterator>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+  /** \brief Base class of all proxy classes that contain
+   *       a (redirectable) reference to an immutable object.
+   *
+   *       \param C the type of the container referred to
+   */
+    template<class C>
+    class container_const_reference:
+        private nonassignable {
+    public:
+        typedef C container_type;
+
+        BOOST_UBLAS_INLINE
+        container_const_reference ():
+            c_ (0) {}
+        BOOST_UBLAS_INLINE
+        container_const_reference (const container_type &c):
+            c_ (&c) {}
+
+        BOOST_UBLAS_INLINE
+        const container_type &operator () () const {
+            return *c_;
+        }
+
+        BOOST_UBLAS_INLINE
+        container_const_reference &assign (const container_type *c) {
+            c_ = c;
+            return *this;
+        }
+        
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const container_const_reference &cr) const {
+            return c_ == cr.c_;
+        }
+
+    private:
+        const container_type *c_;
+    };
+
+  /** \brief Base class of all proxy classes that contain
+   *         a (redirectable) reference to a mutable object.
+   *
+   * \param C the type of the container referred to
+   */
+    template<class C>
+    class container_reference:
+        private nonassignable {
+    public:
+        typedef C container_type;
+
+        BOOST_UBLAS_INLINE
+        container_reference ():
+            c_ (0) {}
+        BOOST_UBLAS_INLINE
+        container_reference (container_type &c):
+            c_ (&c) {}
+
+        BOOST_UBLAS_INLINE
+        container_type &operator () () const {
+           return *c_;
+        }
+
+        BOOST_UBLAS_INLINE
+        container_reference &assign (container_type *c) {
+            c_ = c;
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const container_reference &cr) const {
+            return c_ == cr.c_;
+        }
+
+    private:
+        container_type *c_;
+    };
+
+  /** \brief Base class of all forward iterators.
+   * 
+   *  \param IC the iterator category
+   *  \param I the derived iterator type
+   *  \param T the value type
+   * 
+   * The forward iterator can only proceed in one direction
+   * via the post increment operator.
+   */
+    template<class IC, class I, class T>
+    struct forward_iterator_base:
+        public std::iterator<IC, T> {
+        typedef I derived_iterator_type;
+        typedef T derived_value_type;
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        derived_iterator_type operator ++ (int) {
+            derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
+            derived_iterator_type tmp (d);
+            ++ d;
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
+            derived_iterator_type tmp (d);
+            ++ d;
+            return tmp;
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator != (const derived_iterator_type &it) const {
+            const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
+            return ! (*d == it);
+        }
+    };
+
+  /** \brief Base class of all bidirectional iterators.
+   *
+   * \param IC the iterator category
+   * \param I the derived iterator type
+   * \param T the value type
+   *
+   * The bidirectional iterator can proceed in both directions
+   * via the post increment and post decrement operator.
+   */
+    template<class IC, class I, class T>
+    struct bidirectional_iterator_base:
+        public std::iterator<IC, T> {
+        typedef I derived_iterator_type;
+        typedef T derived_value_type;
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        derived_iterator_type operator ++ (int) {
+            derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
+            derived_iterator_type tmp (d);
+            ++ d;
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
+            derived_iterator_type tmp (d);
+            ++ d;
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        derived_iterator_type operator -- (int) {
+            derived_iterator_type &d (*static_cast<const derived_iterator_type *> (this));
+            derived_iterator_type tmp (d);
+            -- d;
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        friend derived_iterator_type operator -- (derived_iterator_type &d, int) {
+            derived_iterator_type tmp (d);
+            -- d;
+            return tmp;
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator != (const derived_iterator_type &it) const {
+            const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
+            return ! (*d == it);
+        }
+    };
+
+  /** \brief Base class of all random access iterators.
+   *
+   * \param IC the iterator category
+   * \param I the derived iterator type
+   * \param T the value type
+   * \param D the difference type, default: std::ptrdiff_t
+   *
+   * The random access iterator can proceed in both directions
+   * via the post increment/decrement operator or in larger steps
+   * via the +, - and +=, -= operators. The random access iterator
+   * is LessThan Comparable.
+   */
+    template<class IC, class I, class T, class D = std::ptrdiff_t>
+    // ISSUE the default for D seems rather dangerous as it can easily be (silently) incorrect
+    struct random_access_iterator_base:
+        public std::iterator<IC, T> {
+        typedef I derived_iterator_type;
+        typedef T derived_value_type;
+        typedef D derived_difference_type;
+
+        /* FIXME Need to explicitly pass derived_reference_type as otherwise I undefined type or forward declared
+        typedef typename derived_iterator_type::reference derived_reference_type;
+        // Indexed element
+        BOOST_UBLAS_INLINE
+        derived_reference_type operator [] (derived_difference_type n) {
+            return *(*this + n);
+        }
+        */
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        derived_iterator_type operator ++ (int) {
+            derived_iterator_type &d (*static_cast<derived_iterator_type *> (this));
+            derived_iterator_type tmp (d);
+            ++ d;
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        friend derived_iterator_type operator ++ (derived_iterator_type &d, int) {
+            derived_iterator_type tmp (d);
+            ++ d;
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        derived_iterator_type operator -- (int) {
+            derived_iterator_type &d (*static_cast<derived_iterator_type *> (this));
+            derived_iterator_type tmp (d);
+            -- d;
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        friend derived_iterator_type operator -- (derived_iterator_type &d, int) {
+            derived_iterator_type tmp (d);
+            -- d;
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        derived_iterator_type operator + (derived_difference_type n) const {
+            derived_iterator_type tmp (*static_cast<const derived_iterator_type *> (this));
+            return tmp += n;
+        }
+        BOOST_UBLAS_INLINE
+        friend derived_iterator_type operator + (const derived_iterator_type &d, derived_difference_type n) {
+            derived_iterator_type tmp (d);
+            return tmp += n;
+        }
+        BOOST_UBLAS_INLINE
+        friend derived_iterator_type operator + (derived_difference_type n, const derived_iterator_type &d) {
+            derived_iterator_type tmp (d);
+            return tmp += n;
+        }
+        BOOST_UBLAS_INLINE
+        derived_iterator_type operator - (derived_difference_type n) const {
+            derived_iterator_type tmp (*static_cast<const derived_iterator_type *> (this));
+            return tmp -= n;
+        }
+        BOOST_UBLAS_INLINE
+        friend derived_iterator_type operator - (const derived_iterator_type &d, derived_difference_type n) {
+            derived_iterator_type tmp (d);
+            return tmp -= n;
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator != (const derived_iterator_type &it) const {
+            const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
+            return ! (*d == it);
+        }
+        BOOST_UBLAS_INLINE
+        bool operator <= (const derived_iterator_type &it) const {
+            const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
+            return ! (it < *d);
+        }
+        BOOST_UBLAS_INLINE
+        bool operator >= (const derived_iterator_type &it) const {
+            const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
+            return ! (*d < it);
+        }
+        BOOST_UBLAS_INLINE
+        bool operator > (const derived_iterator_type &it) const {
+            const derived_iterator_type *d = static_cast<const derived_iterator_type *> (this);
+            return it < *d;
+        }
+    };
+
+  /** \brief Base class of all reverse iterators. (non-MSVC version)
+   *
+   * \param I the derived iterator type
+   * \param T the value type
+   * \param R the reference type
+   *
+   * The reverse iterator implements a bidirectional iterator
+   * reversing the elements of the underlying iterator. It
+   * implements most operators of a random access iterator.
+   *
+   * uBLAS extension: it.index()
+   */
+
+    // Renamed this class from reverse_iterator to get
+    // typedef reverse_iterator<...> reverse_iterator
+    // working. Thanks to Gabriel Dos Reis for explaining this.
+    template <class I>
+    class reverse_iterator_base:
+        public std::reverse_iterator<I> {
+    public:
+        typedef typename I::container_type container_type;
+        typedef typename container_type::size_type size_type;
+        typedef typename I::difference_type difference_type;
+        typedef I iterator_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base ():
+            std::reverse_iterator<iterator_type> () {}
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base (const iterator_type &it):
+            std::reverse_iterator<iterator_type> (it) {}
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base &operator ++ () {
+            return *this = -- this->base ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base operator ++ (int) {
+            reverse_iterator_base tmp (*this);
+            *this = -- this->base ();
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base &operator -- () {
+            return *this = ++ this->base ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base operator -- (int) {
+            reverse_iterator_base tmp (*this);
+            *this = ++ this->base ();
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base &operator += (difference_type n) {
+            return *this = this->base () - n;
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base &operator -= (difference_type n) {
+            return *this = this->base () + n;
+        }
+
+        BOOST_UBLAS_INLINE
+        friend reverse_iterator_base operator + (const reverse_iterator_base &it, difference_type n) {
+            reverse_iterator_base tmp (it);
+            return tmp += n;
+        }
+        BOOST_UBLAS_INLINE
+        friend reverse_iterator_base operator + (difference_type n, const reverse_iterator_base &it) {
+            reverse_iterator_base tmp (it);
+            return tmp += n;
+        }
+        BOOST_UBLAS_INLINE
+        friend reverse_iterator_base operator - (const reverse_iterator_base &it, difference_type n) {
+            reverse_iterator_base tmp (it);
+            return tmp -= n;
+        }
+        BOOST_UBLAS_INLINE
+        friend difference_type operator - (const reverse_iterator_base &it1, const reverse_iterator_base &it2) {
+            return it2.base () - it1.base ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const container_type &operator () () const {
+            return this->base () ();
+        }
+
+        BOOST_UBLAS_INLINE
+        size_type index () const {
+            iterator_type tmp (this->base ());
+            return (-- tmp).index ();
+        }
+    };
+
+  /** \brief 1st base class of all matrix reverse iterators. (non-MSVC version)
+   *
+   * \param I the derived iterator type
+   *
+   * The reverse iterator implements a bidirectional iterator
+   * reversing the elements of the underlying iterator. It
+   * implements most operators of a random access iterator.
+   *
+   * uBLAS extension: it.index1(), it.index2() and access to
+   * the dual iterator via begin(), end(), rbegin(), rend()
+   */
+
+    // Renamed this class from reverse_iterator1 to get
+    // typedef reverse_iterator1<...> reverse_iterator1
+    // working. Thanks to Gabriel Dos Reis for explaining this.
+    template <class I>
+    class reverse_iterator_base1:
+        public std::reverse_iterator<I> {
+    public:
+        typedef typename I::container_type container_type;
+        typedef typename container_type::size_type size_type;
+        typedef typename I::difference_type difference_type;
+        typedef I iterator_type;
+        typedef typename I::dual_iterator_type dual_iterator_type;
+        typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base1 ():
+            std::reverse_iterator<iterator_type> () {}
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base1 (const iterator_type &it):
+            std::reverse_iterator<iterator_type> (it) {}
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base1 &operator ++ () {
+            return *this = -- this->base ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base1 operator ++ (int) {
+            reverse_iterator_base1 tmp (*this);
+            *this = -- this->base ();
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base1 &operator -- () {
+            return *this = ++ this->base ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base1 operator -- (int) {
+            reverse_iterator_base1 tmp (*this);
+            *this = ++ this->base ();
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base1 &operator += (difference_type n) {
+            return *this = this->base () - n;
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base1 &operator -= (difference_type n) {
+            return *this = this->base () + n;
+        }
+
+        BOOST_UBLAS_INLINE
+        friend reverse_iterator_base1 operator + (const reverse_iterator_base1 &it, difference_type n) {
+            reverse_iterator_base1 tmp (it);
+            return tmp += n;
+        }
+        BOOST_UBLAS_INLINE
+        friend reverse_iterator_base1 operator + (difference_type n, const reverse_iterator_base1 &it) {
+            reverse_iterator_base1 tmp (it);
+            return tmp += n;
+        }
+        BOOST_UBLAS_INLINE
+        friend reverse_iterator_base1 operator - (const reverse_iterator_base1 &it, difference_type n) {
+            reverse_iterator_base1 tmp (it);
+            return tmp -= n;
+        }
+        BOOST_UBLAS_INLINE
+        friend difference_type operator - (const reverse_iterator_base1 &it1, const reverse_iterator_base1 &it2) {
+            return it2.base () - it1.base ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const container_type &operator () () const {
+            return this->base () ();
+        }
+
+        BOOST_UBLAS_INLINE
+        size_type index1 () const {
+            iterator_type tmp (this->base ());
+            return (-- tmp).index1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type index2 () const {
+            iterator_type tmp (this->base ());
+            return (-- tmp).index2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        dual_iterator_type begin () const {
+            iterator_type tmp (this->base ());
+            return (-- tmp).begin ();
+        }
+        BOOST_UBLAS_INLINE
+        dual_iterator_type end () const {
+            iterator_type tmp (this->base ());
+            return (-- tmp).end ();
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rbegin () const {
+            return dual_reverse_iterator_type (end ());
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rend () const {
+            return dual_reverse_iterator_type (begin ());
+        }
+    };
+
+  /** \brief 2nd base class of all matrix reverse iterators. (non-MSVC version)
+   *
+   * \param I the derived iterator type
+   *
+   * The reverse iterator implements a bidirectional iterator
+   * reversing the elements of the underlying iterator. It
+   * implements most operators of a random access iterator.
+   *
+   * uBLAS extension: it.index1(), it.index2() and access to
+   * the dual iterator via begin(), end(), rbegin(), rend()
+   *
+   * Note: this type is _identical_ to reverse_iterator_base1
+   */
+
+    // Renamed this class from reverse_iterator2 to get
+    // typedef reverse_iterator2<...> reverse_iterator2
+    // working. Thanks to Gabriel Dos Reis for explaining this.
+    template <class I>
+    class reverse_iterator_base2:
+        public std::reverse_iterator<I> {
+    public:
+        typedef typename I::container_type container_type;
+        typedef typename container_type::size_type size_type;
+        typedef typename I::difference_type difference_type;
+        typedef I iterator_type;
+        typedef typename I::dual_iterator_type dual_iterator_type;
+        typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base2 ():
+            std::reverse_iterator<iterator_type> () {}
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base2 (const iterator_type &it):
+            std::reverse_iterator<iterator_type> (it) {}
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base2 &operator ++ () {
+            return *this = -- this->base ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base2 operator ++ (int) {
+            reverse_iterator_base2 tmp (*this);
+            *this = -- this->base ();
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base2 &operator -- () {
+            return *this = ++ this->base ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base2 operator -- (int) {
+            reverse_iterator_base2 tmp (*this);
+            *this = ++ this->base ();
+            return tmp;
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base2 &operator += (difference_type n) {
+            return *this = this->base () - n;
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator_base2 &operator -= (difference_type n) {
+            return *this = this->base () + n;
+        }
+
+        BOOST_UBLAS_INLINE
+        friend reverse_iterator_base2 operator + (const reverse_iterator_base2 &it, difference_type n) {
+            reverse_iterator_base2 tmp (it);
+            return tmp += n;
+        }
+        BOOST_UBLAS_INLINE
+        friend reverse_iterator_base2 operator + (difference_type n, const reverse_iterator_base2 &it) {
+            reverse_iterator_base2 tmp (it);
+            return tmp += n;
+        }
+        BOOST_UBLAS_INLINE
+        friend reverse_iterator_base2 operator - (const reverse_iterator_base2 &it, difference_type n) {
+            reverse_iterator_base2 tmp (it);
+            return tmp -= n;
+        }
+        BOOST_UBLAS_INLINE
+        friend difference_type operator - (const reverse_iterator_base2 &it1, const reverse_iterator_base2 &it2) {
+            return it2.base () - it1.base ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const container_type &operator () () const {
+            return this->base () ();
+        }
+
+        BOOST_UBLAS_INLINE
+        size_type index1 () const {
+            iterator_type tmp (this->base ());
+            return (-- tmp).index1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type index2 () const {
+            iterator_type tmp (this->base ());
+            return (-- tmp).index2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        dual_iterator_type begin () const {
+            iterator_type tmp (this->base ());
+            return (-- tmp).begin ();
+        }
+        BOOST_UBLAS_INLINE
+        dual_iterator_type end () const {
+            iterator_type tmp (this->base ());
+            return (-- tmp).end ();
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rbegin () const {
+            return dual_reverse_iterator_type (end ());
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rend () const {
+            return dual_reverse_iterator_type (begin ());
+        }
+    };
+
+  /** \brief A class implementing an indexed random access iterator.
+   *
+   * \param C the (mutable) container type
+   * \param IC the iterator category
+   *
+   * This class implements a random access iterator. The current 
+   * position is stored as the unsigned integer it_ and the
+   * values are accessed via operator()(it_) of the container.
+   *
+   * uBLAS extension: index()
+   */
+
+    template<class C, class IC>
+    class indexed_iterator:
+        public container_reference<C>,
+        public random_access_iterator_base<IC,
+                                           indexed_iterator<C, IC>,
+                                           typename C::value_type,
+                                           typename C::difference_type> {
+    public:
+        typedef C container_type;
+        typedef IC iterator_category;
+        typedef typename container_type::size_type size_type;
+        typedef typename container_type::difference_type difference_type;
+        typedef typename container_type::value_type value_type;
+        typedef typename container_type::reference reference;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        indexed_iterator ():
+            container_reference<container_type> (), it_ () {}
+        BOOST_UBLAS_INLINE
+        indexed_iterator (container_type &c, size_type it):
+            container_reference<container_type> (c), it_ (it) {}
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        indexed_iterator &operator ++ () {
+            ++ it_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_iterator &operator -- () {
+            -- it_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_iterator &operator += (difference_type n) {
+            it_ += n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_iterator &operator -= (difference_type n) {
+            it_ -= n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        difference_type operator - (const indexed_iterator &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            return it_ - it.it_;
+        }
+
+        // Dereference
+        BOOST_UBLAS_INLINE
+        reference operator * () const {
+            BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+            return (*this) () (it_);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (difference_type n) const {
+            return *((*this) + n);
+        }
+
+        // Index
+        BOOST_UBLAS_INLINE
+        size_type index () const {
+            return it_;
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        indexed_iterator &operator = (const indexed_iterator &it) {
+            // FIX: ICC needs full qualification?!
+            // assign (&it ());
+            container_reference<C>::assign (&it ());
+            it_ = it.it_;
+            return *this;
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const indexed_iterator &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            return it_ == it.it_;
+        }
+        BOOST_UBLAS_INLINE
+        bool operator < (const indexed_iterator &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            return it_ < it.it_;
+        }
+
+    private:
+        size_type it_;
+    };
+
+  /** \brief A class implementing an indexed random access iterator.
+   *
+   * \param C the (immutable) container type
+   * \param IC the iterator category
+   *
+   * This class implements a random access iterator. The current 
+   * position is stored as the unsigned integer \c it_ and the
+   * values are accessed via \c operator()(it_) of the container.
+   *
+   * uBLAS extension: \c index()
+   *
+   * Note: there is an automatic conversion from 
+   * \c indexed_iterator to \c indexed_const_iterator
+   */
+
+    template<class C, class IC>
+    class indexed_const_iterator:
+        public container_const_reference<C>,
+        public random_access_iterator_base<IC,
+                                           indexed_const_iterator<C, IC>,
+                                           typename C::value_type,
+                                           typename C::difference_type> {
+    public:
+        typedef C container_type;
+        typedef IC iterator_category;
+        typedef typename container_type::size_type size_type;
+        typedef typename container_type::difference_type difference_type;
+        typedef typename container_type::value_type value_type;
+        typedef typename container_type::const_reference reference;
+        typedef indexed_iterator<container_type, iterator_category> iterator_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator ():
+            container_const_reference<container_type> (), it_ () {}
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator (const container_type &c, size_type it):
+            container_const_reference<container_type> (c), it_ (it) {}
+        BOOST_UBLAS_INLINE 
+        indexed_const_iterator (const iterator_type &it):
+            container_const_reference<container_type> (it ()), it_ (it.index ()) {}
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator &operator ++ () {
+            ++ it_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator &operator -- () {
+            -- it_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator &operator += (difference_type n) {
+            it_ += n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator &operator -= (difference_type n) {
+            it_ -= n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        difference_type operator - (const indexed_const_iterator &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            return it_ - it.it_;
+        }
+
+        // Dereference
+        BOOST_UBLAS_INLINE
+        reference operator * () const {
+            BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+            return (*this) () (it_);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (difference_type n) const {
+            return *((*this) + n);
+        }
+
+        // Index
+        BOOST_UBLAS_INLINE
+        size_type index () const {
+            return it_;
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator &operator = (const indexed_const_iterator &it) {
+            // FIX: ICC needs full qualification?!
+            // assign (&it ());
+            container_const_reference<C>::assign (&it ());
+            it_ = it.it_;
+            return *this;
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const indexed_const_iterator &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            return it_ == it.it_;
+        }
+        BOOST_UBLAS_INLINE
+        bool operator < (const indexed_const_iterator &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            return it_ < it.it_;
+        }
+
+    private:
+        size_type it_;
+
+        friend class indexed_iterator<container_type, iterator_category>;
+    };
+
+    template<class C, class IC>
+    class indexed_iterator2;
+
+  /** \brief A class implementing an indexed random access iterator 
+   * of a matrix.
+   *
+   * \param C the (mutable) container type
+   * \param IC the iterator category
+   *
+   * This class implements a random access iterator. The current
+   * position is stored as two unsigned integers \c it1_ and \c it2_
+   * and the values are accessed via \c operator()(it1_, it2_) of the
+   * container. The iterator changes the first index.
+   *
+   * uBLAS extension: \c index1(), \c index2() and access to the
+   * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
+   *
+   * Note: The container has to support the \code find2(rank, i, j) \endcode 
+   * method
+   */
+
+    template<class C, class IC>
+    class indexed_iterator1:
+        public container_reference<C>, 
+        public random_access_iterator_base<IC,
+                                           indexed_iterator1<C, IC>, 
+                                           typename C::value_type,
+                                           typename C::difference_type> {
+    public:
+        typedef C container_type;
+        typedef IC iterator_category;
+        typedef typename container_type::size_type size_type;
+        typedef typename container_type::difference_type difference_type;
+        typedef typename container_type::value_type value_type;
+        typedef typename container_type::reference reference;
+
+        typedef indexed_iterator2<container_type, iterator_category> dual_iterator_type;
+        typedef reverse_iterator_base2<dual_iterator_type> dual_reverse_iterator_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        indexed_iterator1 ():
+            container_reference<container_type> (), it1_ (), it2_ () {}
+        BOOST_UBLAS_INLINE 
+        indexed_iterator1 (container_type &c, size_type it1, size_type it2):
+            container_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        indexed_iterator1 &operator ++ () {
+            ++ it1_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_iterator1 &operator -- () {
+            -- it1_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_iterator1 &operator += (difference_type n) {
+            it1_ += n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_iterator1 &operator -= (difference_type n) {
+            it1_ -= n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        difference_type operator - (const indexed_iterator1 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+            return it1_ - it.it1_;
+        }
+
+        // Dereference
+        BOOST_UBLAS_INLINE
+        reference operator * () const {
+            BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+            return (*this) () (it1_, it2_);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (difference_type n) const {
+            return *((*this) + n);
+        }
+
+        // Index
+        BOOST_UBLAS_INLINE
+        size_type index1 () const {
+            return it1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type index2 () const {
+            return it2_;
+        }
+
+        BOOST_UBLAS_INLINE
+        dual_iterator_type begin () const {
+            return (*this) ().find2 (1, index1 (), 0); 
+        }
+        BOOST_UBLAS_INLINE
+        dual_iterator_type end () const {
+            return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rbegin () const {
+            return dual_reverse_iterator_type (end ());
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rend () const {
+            return dual_reverse_iterator_type (begin ());
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        indexed_iterator1 &operator = (const indexed_iterator1 &it) {
+            // FIX: ICC needs full qualification?!
+            // assign (&it ());
+            container_reference<C>::assign (&it ());
+            it1_ = it.it1_;
+            it2_ = it.it2_;
+            return *this;
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const indexed_iterator1 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+            return it1_ == it.it1_;
+        }
+        BOOST_UBLAS_INLINE
+        bool operator < (const indexed_iterator1 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+            return it1_ < it.it1_;
+        }
+
+    private:
+        size_type it1_;
+        size_type it2_;
+    };
+
+    template<class C, class IC>
+    class indexed_const_iterator2;
+
+  /** \brief A class implementing an indexed random access iterator 
+   * of a matrix.
+   *
+   * \param C the (immutable) container type
+   * \param IC the iterator category
+   *
+   * This class implements a random access iterator. The current
+   * position is stored as two unsigned integers \c it1_ and \c it2_
+   * and the values are accessed via \c operator()(it1_, it2_) of the
+   * container. The iterator changes the first index.
+   *
+   * uBLAS extension: \c index1(), \c index2() and access to the
+   * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
+   *
+   * Note 1: The container has to support the find2(rank, i, j) method
+   *
+   * Note 2: there is an automatic conversion from 
+   * \c indexed_iterator1 to \c indexed_const_iterator1
+   */
+
+    template<class C, class IC>
+    class indexed_const_iterator1:
+        public container_const_reference<C>, 
+        public random_access_iterator_base<IC,
+                                           indexed_const_iterator1<C, IC>, 
+                                           typename C::value_type,
+                                           typename C::difference_type> {
+    public:
+        typedef C container_type;
+        typedef IC iterator_category;
+        typedef typename container_type::size_type size_type;
+        typedef typename container_type::difference_type difference_type;
+        typedef typename container_type::value_type value_type;
+        typedef typename container_type::const_reference reference;
+
+        typedef indexed_iterator1<container_type, iterator_category> iterator_type;
+        typedef indexed_const_iterator2<container_type, iterator_category> dual_iterator_type;
+        typedef reverse_iterator_base2<dual_iterator_type> dual_reverse_iterator_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator1 ():
+            container_const_reference<container_type> (), it1_ (), it2_ () {}
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator1 (const container_type &c, size_type it1, size_type it2):
+            container_const_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
+        BOOST_UBLAS_INLINE 
+        indexed_const_iterator1 (const iterator_type &it):
+            container_const_reference<container_type> (it ()), it1_ (it.index1 ()), it2_ (it.index2 ()) {}
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator1 &operator ++ () {
+            ++ it1_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator1 &operator -- () {
+            -- it1_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator1 &operator += (difference_type n) {
+            it1_ += n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator1 &operator -= (difference_type n) {
+            it1_ -= n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        difference_type operator - (const indexed_const_iterator1 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+            return it1_ - it.it1_;
+        }
+
+        // Dereference
+        BOOST_UBLAS_INLINE
+        reference operator * () const {
+            BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+            return (*this) () (it1_, it2_);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (difference_type n) const {
+            return *((*this) + n);
+        }
+
+        // Index
+        BOOST_UBLAS_INLINE
+        size_type index1 () const {
+            return it1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type index2 () const {
+            return it2_;
+        }
+
+        BOOST_UBLAS_INLINE
+        dual_iterator_type begin () const {
+            return (*this) ().find2 (1, index1 (), 0); 
+        }
+        BOOST_UBLAS_INLINE
+        dual_iterator_type end () const {
+            return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); 
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rbegin () const {
+            return dual_reverse_iterator_type (end ()); 
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rend () const {
+            return dual_reverse_iterator_type (begin ()); 
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator1 &operator = (const indexed_const_iterator1 &it) {
+            // FIX: ICC needs full qualification?!
+            // assign (&it ());
+            container_const_reference<C>::assign (&it ());
+            it1_ = it.it1_;
+            it2_ = it.it2_;
+            return *this;
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const indexed_const_iterator1 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+            return it1_ == it.it1_;
+        }
+        BOOST_UBLAS_INLINE
+        bool operator < (const indexed_const_iterator1 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+            return it1_ < it.it1_;
+        }
+
+    private:
+        size_type it1_;
+        size_type it2_;
+
+        friend class indexed_iterator1<container_type, iterator_category>;
+    };
+
+  /** \brief A class implementing an indexed random access iterator 
+   * of a matrix.
+   *
+   * \param C the (mutable) container type
+   * \param IC the iterator category
+   *
+   * This class implements a random access iterator. The current
+   * position is stored as two unsigned integers \c it1_ and \c it2_
+   * and the values are accessed via \c operator()(it1_, it2_) of the
+   * container. The iterator changes the second index.
+   *
+   * uBLAS extension: \c index1(), \c index2() and access to the
+   * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
+   *
+   * Note: The container has to support the find1(rank, i, j) method
+   */
+    template<class C, class IC>
+    class indexed_iterator2:
+        public container_reference<C>, 
+        public random_access_iterator_base<IC,
+                                           indexed_iterator2<C, IC>, 
+                                           typename C::value_type,
+                                           typename C::difference_type> {
+    public:
+        typedef C container_type;
+        typedef IC iterator_category;
+        typedef typename container_type::size_type size_type;
+        typedef typename container_type::difference_type difference_type;
+        typedef typename container_type::value_type value_type;
+        typedef typename container_type::reference reference;
+
+        typedef indexed_iterator1<container_type, iterator_category> dual_iterator_type;
+        typedef reverse_iterator_base1<dual_iterator_type> dual_reverse_iterator_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        indexed_iterator2 ():
+            container_reference<container_type> (), it1_ (), it2_ () {}
+        BOOST_UBLAS_INLINE
+        indexed_iterator2 (container_type &c, size_type it1, size_type it2):
+            container_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        indexed_iterator2 &operator ++ () {
+            ++ it2_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_iterator2 &operator -- () {
+            -- it2_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_iterator2 &operator += (difference_type n) {
+            it2_ += n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_iterator2 &operator -= (difference_type n) {
+            it2_ -= n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        difference_type operator - (const indexed_iterator2 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+            return it2_ - it.it2_;
+        }
+
+        // Dereference
+        BOOST_UBLAS_INLINE
+        reference operator * () const {
+            BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+            return (*this) () (it1_, it2_);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (difference_type n) const {
+            return *((*this) + n);
+        }
+
+        // Index
+        BOOST_UBLAS_INLINE
+        size_type index1 () const {
+            return it1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type index2 () const {
+            return it2_;
+        }
+
+        BOOST_UBLAS_INLINE
+        dual_iterator_type begin () const {
+            return (*this) ().find1 (1, 0, index2 ());
+        }
+        BOOST_UBLAS_INLINE
+        dual_iterator_type end () const {
+            return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rbegin () const {
+            return dual_reverse_iterator_type (end ());
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rend () const {
+            return dual_reverse_iterator_type (begin ());
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        indexed_iterator2 &operator = (const indexed_iterator2 &it) {
+            // FIX: ICC needs full qualification?!
+            // assign (&it ());
+            container_reference<C>::assign (&it ());
+            it1_ = it.it1_;
+            it2_ = it.it2_;
+            return *this;
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const indexed_iterator2 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+            return it2_ == it.it2_;
+        }
+        BOOST_UBLAS_INLINE
+        bool operator < (const indexed_iterator2 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+            return it2_ < it.it2_;
+        }
+
+    private:
+        size_type it1_;
+        size_type it2_;
+    };
+
+  /** \brief A class implementing an indexed random access iterator 
+   * of a matrix.
+   *
+   * \param C the (immutable) container type
+   * \param IC the iterator category
+   *
+   * This class implements a random access iterator. The current
+   * position is stored as two unsigned integers \c it1_ and \c it2_
+   * and the values are accessed via \c operator()(it1_, it2_) of the
+   * container. The iterator changes the second index.
+   *
+   * uBLAS extension: \c index1(), \c index2() and access to the
+   * dual iterator via \c begin(), \c end(), \c rbegin() and \c rend()
+   *
+   * Note 1: The container has to support the \c find2(rank, i, j) method
+   *
+   * Note 2: there is an automatic conversion from 
+   * \c indexed_iterator2 to \c indexed_const_iterator2
+   */
+
+    template<class C, class IC>
+    class indexed_const_iterator2:
+        public container_const_reference<C>,
+        public random_access_iterator_base<IC,
+                                           indexed_const_iterator2<C, IC>,
+                                           typename C::value_type,
+                                           typename C::difference_type> {
+    public:
+        typedef C container_type;
+        typedef IC iterator_category;
+        typedef typename container_type::size_type size_type;
+        typedef typename container_type::difference_type difference_type;
+        typedef typename container_type::value_type value_type;
+        typedef typename container_type::const_reference reference;
+
+        typedef indexed_iterator2<container_type, iterator_category> iterator_type;
+        typedef indexed_const_iterator1<container_type, iterator_category> dual_iterator_type;
+        typedef reverse_iterator_base1<dual_iterator_type> dual_reverse_iterator_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator2 ():
+            container_const_reference<container_type> (), it1_ (), it2_ () {}
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator2 (const container_type &c, size_type it1, size_type it2):
+            container_const_reference<container_type> (c), it1_ (it1), it2_ (it2) {}
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator2 (const iterator_type &it):
+            container_const_reference<container_type> (it ()), it1_ (it.index1 ()), it2_ (it.index2 ()) {}
+
+        // Arithmetic
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator2 &operator ++ () {
+            ++ it2_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator2 &operator -- () {
+            -- it2_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator2 &operator += (difference_type n) {
+            it2_ += n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator2 &operator -= (difference_type n) {
+            it2_ -= n;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        difference_type operator - (const indexed_const_iterator2 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+            return it2_ - it.it2_;
+        }
+
+        // Dereference
+        BOOST_UBLAS_INLINE
+        reference operator * () const {
+            BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+            return (*this) () (it1_, it2_);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (difference_type n) const {
+            return *((*this) + n);
+        }
+
+        // Index
+        BOOST_UBLAS_INLINE
+        size_type index1 () const {
+            return it1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type index2 () const {
+            return it2_;
+        }
+
+        BOOST_UBLAS_INLINE
+        dual_iterator_type begin () const {
+            return (*this) ().find1 (1, 0, index2 ());
+        }
+        BOOST_UBLAS_INLINE
+        dual_iterator_type end () const {
+            return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rbegin () const {
+            return dual_reverse_iterator_type (end ());
+        }
+        BOOST_UBLAS_INLINE
+        dual_reverse_iterator_type rend () const {
+            return dual_reverse_iterator_type (begin ());
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        indexed_const_iterator2 &operator = (const indexed_const_iterator2 &it) {
+            // FIX: ICC needs full qualification?!
+            // assign (&it ());
+            container_const_reference<C>::assign (&it ());
+            it1_ = it.it1_;
+            it2_ = it.it2_;
+            return *this;
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const indexed_const_iterator2 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+            return it2_ == it.it2_;
+        }
+        BOOST_UBLAS_INLINE
+        bool operator < (const indexed_const_iterator2 &it) const {
+            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+            BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+            return it2_ < it.it2_;
+        }
+
+    private:
+        size_type it1_;
+        size_type it2_;
+
+        friend class indexed_iterator2<container_type, iterator_category>;
+    };
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/detail/matrix_assign.hpp b/include/boost/numeric/ublas/detail/matrix_assign.hpp
new file mode 100644
index 0000000..be172dd
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/matrix_assign.hpp
@@ -0,0 +1,1638 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_MATRIX_ASSIGN_
+#define _BOOST_UBLAS_MATRIX_ASSIGN_
+
+#include <boost/numeric/ublas/traits.hpp>
+// Required for make_conformant storage
+#include <vector>
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+namespace detail {
+    
+    // Weak equality check - useful to compare equality two arbitary matrix 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 matrix_expression<E1> &e1, const matrix_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 matrix_expression<E1> &e1, const matrix_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);
+    }
+
+
+    template<class M, class E, class R>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void make_conformant (M &m, const matrix_expression<E> &e, row_major_tag, R) {
+        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
+        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
+        typedef R conformant_restrict_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        // FIXME unbounded_array with push_back maybe better
+        std::vector<std::pair<size_type, size_type> > index;
+        typename M::iterator1 it1 (m.begin1 ());
+        typename M::iterator1 it1_end (m.end1 ());
+        typename E::const_iterator1 it1e (e ().begin1 ());
+        typename E::const_iterator1 it1e_end (e ().end1 ());
+        while (it1 != it1_end && it1e != it1e_end) {
+            difference_type compare = it1.index1 () - it1e.index1 ();
+            if (compare == 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename M::iterator2 it2 (it1.begin ());
+                typename M::iterator2 it2_end (it1.end ());
+                typename E::const_iterator2 it2e (it1e.begin ());
+                typename E::const_iterator2 it2e_end (it1e.end ());
+#else
+                typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+                typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+                typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
+                typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
+#endif
+                if (it2 != it2_end && it2e != it2e_end) {
+                    size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
+                    while (true) {
+                        difference_type compare2 = it2_index - it2e_index;
+                        if (compare2 == 0) {
+                            ++ it2, ++ it2e;
+                            if (it2 != it2_end && it2e != it2e_end) {
+                                it2_index = it2.index2 ();
+                                it2e_index = it2e.index2 ();
+                            } else
+                                break;
+                        } else if (compare2 < 0) {
+                            increment (it2, it2_end, - compare2);
+                            if (it2 != it2_end)
+                                it2_index = it2.index2 ();
+                            else
+                                break;
+                        } else if (compare2 > 0) {
+                            if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
+                                if (static_cast<value_type>(*it2e) != value_type/*zero*/())
+                                    index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
+                            ++ it2e;
+                            if (it2e != it2e_end)
+                                it2e_index = it2e.index2 ();
+                            else
+                                break;
+                        }
+                    }
+                }
+                while (it2e != it2e_end) {
+                    if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
+                        if (static_cast<value_type>(*it2e) != value_type/*zero*/())
+                            index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
+                    ++ it2e;
+                }
+                ++ it1, ++ it1e;
+            } else if (compare < 0) {
+                increment (it1, it1_end, - compare);
+            } else if (compare > 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename E::const_iterator2 it2e (it1e.begin ());
+                typename E::const_iterator2 it2e_end (it1e.end ());
+#else
+                typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
+                typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
+#endif
+                while (it2e != it2e_end) {
+                    if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
+                        if (static_cast<value_type>(*it2e) != value_type/*zero*/())
+                            index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
+                    ++ it2e;
+                }
+                ++ it1e;
+            }
+        }
+        while (it1e != it1e_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename E::const_iterator2 it2e (it1e.begin ());
+            typename E::const_iterator2 it2e_end (it1e.end ());
+#else
+            typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
+            typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
+#endif
+            while (it2e != it2e_end) {
+                if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
+                    if (static_cast<value_type>(*it2e) != value_type/*zero*/())
+                        index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
+                ++ it2e;
+            }
+            ++ it1e;
+        }
+        // ISSUE proxies require insert_element
+        for (size_type k = 0; k < index.size (); ++ k)
+            m (index [k].first, index [k].second) = value_type/*zero*/();
+    }
+    template<class M, class E, class R>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void make_conformant (M &m, const matrix_expression<E> &e, column_major_tag, R) {
+        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
+        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
+        typedef R conformant_restrict_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        std::vector<std::pair<size_type, size_type> > index;
+        typename M::iterator2 it2 (m.begin2 ());
+        typename M::iterator2 it2_end (m.end2 ());
+        typename E::const_iterator2 it2e (e ().begin2 ());
+        typename E::const_iterator2 it2e_end (e ().end2 ());
+        while (it2 != it2_end && it2e != it2e_end) {
+            difference_type compare = it2.index2 () - it2e.index2 ();
+            if (compare == 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename M::iterator1 it1 (it2.begin ());
+                typename M::iterator1 it1_end (it2.end ());
+                typename E::const_iterator1 it1e (it2e.begin ());
+                typename E::const_iterator1 it1e_end (it2e.end ());
+#else
+                typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+                typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+                typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
+                typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
+#endif
+                if (it1 != it1_end && it1e != it1e_end) {
+                    size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
+                    while (true) {
+                        difference_type compare2 = it1_index - it1e_index;
+                        if (compare2 == 0) {
+                            ++ it1, ++ it1e;
+                            if (it1 != it1_end && it1e != it1e_end) {
+                                it1_index = it1.index1 ();
+                                it1e_index = it1e.index1 ();
+                            } else
+                                break;
+                        } else if (compare2 < 0) {
+                            increment (it1, it1_end, - compare2);
+                            if (it1 != it1_end)
+                                it1_index = it1.index1 ();
+                            else
+                                break;
+                        } else if (compare2 > 0) {
+                            if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
+                                if (static_cast<value_type>(*it1e) != value_type/*zero*/())
+                                    index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
+                            ++ it1e;
+                            if (it1e != it1e_end)
+                                it1e_index = it1e.index1 ();
+                            else
+                                break;
+                        }
+                    }
+                }
+                while (it1e != it1e_end) {
+                    if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
+                        if (static_cast<value_type>(*it1e) != value_type/*zero*/())
+                            index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
+                    ++ it1e;
+                }
+                ++ it2, ++ it2e;
+            } else if (compare < 0) {
+                increment (it2, it2_end, - compare);
+            } else if (compare > 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename E::const_iterator1 it1e (it2e.begin ());
+                typename E::const_iterator1 it1e_end (it2e.end ());
+#else
+                typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
+                typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
+#endif
+                while (it1e != it1e_end) {
+                    if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
+                        if (static_cast<value_type>(*it1e) != value_type/*zero*/())
+                            index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
+                    ++ it1e;
+                }
+                ++ it2e;
+            }
+        }
+        while (it2e != it2e_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename E::const_iterator1 it1e (it2e.begin ());
+            typename E::const_iterator1 it1e_end (it2e.end ());
+#else
+            typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
+            typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
+#endif
+            while (it1e != it1e_end) {
+                if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
+                    if (static_cast<value_type>(*it1e) != value_type/*zero*/())
+                        index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
+                ++ it1e;
+            }
+            ++ it2e;
+        }
+        // ISSUE proxies require insert_element
+        for (size_type k = 0; k < index.size (); ++ k)
+            m (index [k].first, index [k].second) = value_type/*zero*/();
+    }
+
+}//namespace detail
+
+
+    // Explicitly iterating row major
+    template<template <class T1, class T2> class F, class M, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void iterating_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
+        typedef F<typename M::iterator2::reference, T> functor_type;
+        typedef typename M::difference_type difference_type;
+        difference_type size1 (m.size1 ());
+        difference_type size2 (m.size2 ());
+        typename M::iterator1 it1 (m.begin1 ());
+        BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
+        while (-- size1 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator2 it2 (it1.begin ());
+#else
+            typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+#endif
+            BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
+            difference_type temp_size2 (size2);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            while (-- temp_size2 >= 0)
+                functor_type::apply (*it2, t), ++ it2;
+#else
+            DD (temp_size2, 4, r, (functor_type::apply (*it2, t), ++ it2));
+#endif
+            ++ it1;
+        }
+    }
+    // Explicitly iterating column major
+    template<template <class T1, class T2> class F, class M, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void iterating_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
+        typedef F<typename M::iterator1::reference, T> functor_type;
+        typedef typename M::difference_type difference_type;
+        difference_type size2 (m.size2 ());
+        difference_type size1 (m.size1 ());
+        typename M::iterator2 it2 (m.begin2 ());
+        BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
+        while (-- size2 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator1 it1 (it2.begin ());
+#else
+            typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+#endif
+            BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
+            difference_type temp_size1 (size1);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            while (-- temp_size1 >= 0)
+                functor_type::apply (*it1, t), ++ it1;
+#else
+            DD (temp_size1, 4, r, (functor_type::apply (*it1, t), ++ it1));
+#endif
+            ++ it2;
+        }
+    }
+    // Explicitly indexing row major
+    template<template <class T1, class T2> class F, class M, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void indexing_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
+        typedef F<typename M::reference, T> functor_type;
+        typedef typename M::size_type size_type;
+        size_type size1 (m.size1 ());
+        size_type size2 (m.size2 ());
+        for (size_type i = 0; i < size1; ++ i) {
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            for (size_type j = 0; j < size2; ++ j)
+                functor_type::apply (m (i, j), t);
+#else
+            size_type j (0);
+            DD (size2, 4, r, (functor_type::apply (m (i, j), t), ++ j));
+#endif
+        }
+    }
+    // Explicitly indexing column major
+    template<template <class T1, class T2> class F, class M, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void indexing_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
+        typedef F<typename M::reference, T> functor_type;
+        typedef typename M::size_type size_type;
+        size_type size2 (m.size2 ());
+        size_type size1 (m.size1 ());
+        for (size_type j = 0; j < size2; ++ j) {
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            for (size_type i = 0; i < size1; ++ i)
+                functor_type::apply (m (i, j), t);
+#else
+            size_type i (0);
+            DD (size1, 4, r, (functor_type::apply (m (i, j), t), ++ i));
+#endif
+        }
+    }
+
+    // Dense (proxy) case
+    template<template <class T1, class T2> class F, class M, class T, class C>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign_scalar (M &m, const T &t, dense_proxy_tag, C) {
+        typedef C orientation_category;
+#ifdef BOOST_UBLAS_USE_INDEXING
+        indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
+#elif BOOST_UBLAS_USE_ITERATING
+        iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
+#else
+        typedef typename M::size_type size_type;
+        size_type size1 (m.size1 ());
+        size_type size2 (m.size2 ());
+        if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
+            size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
+            iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
+        else
+            indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
+#endif
+    }
+    // Packed (proxy) row major case
+    template<template <class T1, class T2> class F, class M, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, row_major_tag) {
+        typedef F<typename M::iterator2::reference, T> functor_type;
+        typedef typename M::difference_type difference_type;
+        typename M::iterator1 it1 (m.begin1 ());
+        difference_type size1 (m.end1 () - it1);
+        while (-- size1 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator2 it2 (it1.begin ());
+            difference_type size2 (it1.end () - it2);
+#else
+            typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+            difference_type size2 (end (it1, iterator1_tag ()) - it2);
+#endif
+            while (-- size2 >= 0)
+                functor_type::apply (*it2, t), ++ it2;
+            ++ it1;
+        }
+    }
+    // Packed (proxy) column major case
+    template<template <class T1, class T2> class F, class M, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, column_major_tag) {
+        typedef F<typename M::iterator1::reference, T> functor_type;
+        typedef typename M::difference_type difference_type;
+        typename M::iterator2 it2 (m.begin2 ());
+        difference_type size2 (m.end2 () - it2);
+        while (-- size2 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator1 it1 (it2.begin ());
+            difference_type size1 (it2.end () - it1);
+#else
+            typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+            difference_type size1 (end (it2, iterator2_tag ()) - it1);
+#endif
+            while (-- size1 >= 0)
+                functor_type::apply (*it1, t), ++ it1;
+            ++ it2;
+        }
+    }
+    // Sparse (proxy) row major case
+    template<template <class T1, class T2> class F, class M, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, row_major_tag) {
+        typedef F<typename M::iterator2::reference, T> functor_type;
+        typename M::iterator1 it1 (m.begin1 ());
+        typename M::iterator1 it1_end (m.end1 ());
+        while (it1 != it1_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator2 it2 (it1.begin ());
+            typename M::iterator2 it2_end (it1.end ());
+#else
+            typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+            typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+#endif
+            while (it2 != it2_end)
+                functor_type::apply (*it2, t), ++ it2;
+            ++ it1;
+        }
+    }
+    // Sparse (proxy) column major case
+    template<template <class T1, class T2> class F, class M, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, column_major_tag) {
+        typedef F<typename M::iterator1::reference, T> functor_type;
+        typename M::iterator2 it2 (m.begin2 ());
+        typename M::iterator2 it2_end (m.end2 ());
+        while (it2 != it2_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator1 it1 (it2.begin ());
+            typename M::iterator1 it1_end (it2.end ());
+#else
+            typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+            typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+#endif
+            while (it1 != it1_end)
+                functor_type::apply (*it1, t), ++ it1;
+            ++ it2;
+        }
+    }
+
+    // Dispatcher
+    template<template <class T1, class T2> class F, class M, class T>
+    BOOST_UBLAS_INLINE
+    void matrix_assign_scalar (M &m, const T &t) {
+        typedef typename M::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+        matrix_assign_scalar<F> (m, t, storage_category (), orientation_category ());
+    }
+
+    template<class SC, bool COMPUTED, class RI1, class RI2>
+    struct matrix_assign_traits {
+        typedef SC storage_category;
+    };
+
+    template<bool COMPUTED>
+    struct matrix_assign_traits<dense_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
+        typedef packed_tag storage_category;
+    };
+    template<>
+    struct matrix_assign_traits<dense_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_tag storage_category;
+    };
+    template<>
+    struct matrix_assign_traits<dense_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<bool COMPUTED>
+    struct matrix_assign_traits<dense_proxy_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
+        typedef packed_proxy_tag storage_category;
+    };
+    template<bool COMPUTED>
+    struct matrix_assign_traits<dense_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<>
+    struct matrix_assign_traits<packed_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_tag storage_category;
+    };
+    template<>
+    struct matrix_assign_traits<packed_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<bool COMPUTED>
+    struct matrix_assign_traits<packed_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<>
+    struct matrix_assign_traits<sparse_tag, true, dense_random_access_iterator_tag, dense_random_access_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+    template<>
+    struct matrix_assign_traits<sparse_tag, true, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+    template<>
+    struct matrix_assign_traits<sparse_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    // Explicitly iterating row major
+    template<template <class T1, class T2> class F, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void iterating_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
+        typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
+        typedef typename M::difference_type difference_type;
+        difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
+        difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
+        typename M::iterator1 it1 (m.begin1 ());
+        BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
+        typename E::const_iterator1 it1e (e ().begin1 ());
+        BOOST_UBLAS_CHECK (size2 == 0 || e ().end1 () - it1e == size1, bad_size ());
+        while (-- size1 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator2 it2 (it1.begin ());
+            typename E::const_iterator2 it2e (it1e.begin ());
+#else
+            typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+            typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
+#endif
+            BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
+            BOOST_UBLAS_CHECK (it1e.end () - it2e == size2, bad_size ());
+            difference_type temp_size2 (size2);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            while (-- temp_size2 >= 0)
+                functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
+#else
+            DD (temp_size2, 2, r, (functor_type::apply (*it2, *it2e), ++ it2, ++ it2e));
+#endif
+            ++ it1, ++ it1e;
+        }
+    }
+    // Explicitly iterating column major
+    template<template <class T1, class T2> class F, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void iterating_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
+        typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
+        typedef typename M::difference_type difference_type;
+        difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
+        difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
+        typename M::iterator2 it2 (m.begin2 ());
+        BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
+        typename E::const_iterator2 it2e (e ().begin2 ());
+        BOOST_UBLAS_CHECK (size1 == 0 || e ().end2 () - it2e == size2, bad_size ());
+        while (-- size2 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator1 it1 (it2.begin ());
+            typename E::const_iterator1 it1e (it2e.begin ());
+#else
+            typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+            typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
+#endif
+            BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
+            BOOST_UBLAS_CHECK (it2e.end () - it1e == size1, bad_size ());
+            difference_type temp_size1 (size1);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            while (-- temp_size1 >= 0)
+                functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
+#else
+            DD (temp_size1, 2, r, (functor_type::apply (*it1, *it1e), ++ it1, ++ it1e));
+#endif
+            ++ it2, ++ it2e;
+        }
+    }
+    // Explicitly indexing row major
+    template<template <class T1, class T2> class F, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void indexing_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
+        typedef F<typename M::reference, typename E::value_type> functor_type;
+        typedef typename M::size_type size_type;
+        size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
+        size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
+        for (size_type i = 0; i < size1; ++ i) {
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            for (size_type j = 0; j < size2; ++ j)
+                functor_type::apply (m (i, j), e () (i, j));
+#else
+            size_type j (0);
+            DD (size2, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ j));
+#endif
+        }
+    }
+    // Explicitly indexing column major
+    template<template <class T1, class T2> class F, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void indexing_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
+        typedef F<typename M::reference, typename E::value_type> functor_type;
+        typedef typename M::size_type size_type;
+        size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
+        size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
+        for (size_type j = 0; j < size2; ++ j) {
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            for (size_type i = 0; i < size1; ++ i)
+                functor_type::apply (m (i, j), e () (i, j));
+#else
+            size_type i (0);
+            DD (size1, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ i));
+#endif
+        }
+    }
+
+    // Dense (proxy) case
+    template<template <class T1, class T2> class F, class R, class M, class E, class C>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign (M &m, const matrix_expression<E> &e, dense_proxy_tag, C) {
+        // R unnecessary, make_conformant not required
+        typedef C orientation_category;
+#ifdef BOOST_UBLAS_USE_INDEXING
+        indexing_matrix_assign<F> (m, e, orientation_category ());
+#elif BOOST_UBLAS_USE_ITERATING
+        iterating_matrix_assign<F> (m, e, orientation_category ());
+#else
+        typedef typename M::difference_type difference_type;
+        size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
+        size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
+        if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
+            size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
+            iterating_matrix_assign<F> (m, e, orientation_category ());
+        else
+            indexing_matrix_assign<F> (m, e, orientation_category ());
+#endif
+    }
+    // Packed (proxy) row major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
+        typedef typename matrix_traits<E>::value_type expr_value_type;
+        typedef F<typename M::iterator2::reference, expr_value_type> functor_type;
+        // R unnecessary, make_conformant not required
+        typedef typename M::difference_type difference_type;
+
+        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
+        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
+
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef typename M::value_type value_type;
+        matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
+        indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
+        indexing_matrix_assign<F> (cm, e, row_major_tag ());
+#endif
+        typename M::iterator1 it1 (m.begin1 ());
+        typename M::iterator1 it1_end (m.end1 ());
+        typename E::const_iterator1 it1e (e ().begin1 ());
+        typename E::const_iterator1 it1e_end (e ().end1 ());
+        difference_type it1_size (it1_end - it1);
+        difference_type it1e_size (it1e_end - it1e);
+        difference_type diff1 (0);
+        if (it1_size > 0 && it1e_size > 0)
+            diff1 = it1.index1 () - it1e.index1 ();
+        if (diff1 != 0) {
+            difference_type size1 = (std::min) (diff1, it1e_size);
+            if (size1 > 0) {
+                it1e += size1;
+                it1e_size -= size1;
+                diff1 -= size1;
+            }
+            size1 = (std::min) (- diff1, it1_size);
+            if (size1 > 0) {
+                it1_size -= size1;
+                if (!functor_type::computed) {
+                    while (-- size1 >= 0) { // zeroing
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                        typename M::iterator2 it2 (it1.begin ());
+                        typename M::iterator2 it2_end (it1.end ());
+#else
+                        typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+                        typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+#endif
+                        difference_type size2 (it2_end - it2);
+                        while (-- size2 >= 0)
+                            functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
+                        ++ it1;
+                    }
+                } else {
+                    it1 += size1;
+                }
+                diff1 += size1;
+            }
+        }
+        difference_type size1 ((std::min) (it1_size, it1e_size));
+        it1_size -= size1;
+        it1e_size -= size1;
+        while (-- size1 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator2 it2 (it1.begin ());
+            typename M::iterator2 it2_end (it1.end ());
+            typename E::const_iterator2 it2e (it1e.begin ());
+            typename E::const_iterator2 it2e_end (it1e.end ());
+#else
+            typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+            typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+            typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
+            typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
+#endif
+            difference_type it2_size (it2_end - it2);
+            difference_type it2e_size (it2e_end - it2e);
+            difference_type diff2 (0);
+            if (it2_size > 0 && it2e_size > 0) {
+                diff2 = it2.index2 () - it2e.index2 ();
+                difference_type size2 = (std::min) (diff2, it2e_size);
+                if (size2 > 0) {
+                    it2e += size2;
+                    it2e_size -= size2;
+                    diff2 -= size2;
+                }
+                size2 = (std::min) (- diff2, it2_size);
+                if (size2 > 0) {
+                    it2_size -= size2;
+                    if (!functor_type::computed) {
+                        while (-- size2 >= 0)   // zeroing
+                            functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
+                    } else {
+                        it2 += size2;
+                    }
+                    diff2 += size2;
+                }
+            }
+            difference_type size2 ((std::min) (it2_size, it2e_size));
+            it2_size -= size2;
+            it2e_size -= size2;
+            while (-- size2 >= 0)
+                functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
+            size2 = it2_size;
+            if (!functor_type::computed) {
+                while (-- size2 >= 0)   // zeroing
+                    functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
+            } else {
+                it2 += size2;
+            }
+            ++ it1, ++ it1e;
+        }
+        size1 = it1_size;
+        if (!functor_type::computed) {
+            while (-- size1 >= 0) { // zeroing
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename M::iterator2 it2 (it1.begin ());
+                typename M::iterator2 it2_end (it1.end ());
+#else
+                typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+                typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+#endif
+                difference_type size2 (it2_end - it2);
+                while (-- size2 >= 0)
+                    functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
+                ++ it1;
+            }
+        } else {
+            it1 += size1;
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        if (! disable_type_check<bool>::value)
+            BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
+#endif
+    }
+    // Packed (proxy) column major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
+        typedef typename matrix_traits<E>::value_type expr_value_type;
+        typedef F<typename M::iterator1::reference, expr_value_type> functor_type;
+        // R unnecessary, make_conformant not required
+        typedef typename M::difference_type difference_type;
+
+        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
+
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef typename M::value_type value_type;
+        matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
+        indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
+        indexing_matrix_assign<F> (cm, e, column_major_tag ());
+#endif
+        typename M::iterator2 it2 (m.begin2 ());
+        typename M::iterator2 it2_end (m.end2 ());
+        typename E::const_iterator2 it2e (e ().begin2 ());
+        typename E::const_iterator2 it2e_end (e ().end2 ());
+        difference_type it2_size (it2_end - it2);
+        difference_type it2e_size (it2e_end - it2e);
+        difference_type diff2 (0);
+        if (it2_size > 0 && it2e_size > 0)
+            diff2 = it2.index2 () - it2e.index2 ();
+        if (diff2 != 0) {
+            difference_type size2 = (std::min) (diff2, it2e_size);
+            if (size2 > 0) {
+                it2e += size2;
+                it2e_size -= size2;
+                diff2 -= size2;
+            }
+            size2 = (std::min) (- diff2, it2_size);
+            if (size2 > 0) {
+                it2_size -= size2;
+                if (!functor_type::computed) {
+                    while (-- size2 >= 0) { // zeroing
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                        typename M::iterator1 it1 (it2.begin ());
+                        typename M::iterator1 it1_end (it2.end ());
+#else
+                        typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+                        typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+#endif
+                        difference_type size1 (it1_end - it1);
+                        while (-- size1 >= 0)
+                            functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
+                        ++ it2;
+                    }
+                } else {
+                    it2 += size2;
+                }
+                diff2 += size2;
+            }
+        }
+        difference_type size2 ((std::min) (it2_size, it2e_size));
+        it2_size -= size2;
+        it2e_size -= size2;
+        while (-- size2 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator1 it1 (it2.begin ());
+            typename M::iterator1 it1_end (it2.end ());
+            typename E::const_iterator1 it1e (it2e.begin ());
+            typename E::const_iterator1 it1e_end (it2e.end ());
+#else
+            typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+            typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+            typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
+            typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
+#endif
+            difference_type it1_size (it1_end - it1);
+            difference_type it1e_size (it1e_end - it1e);
+            difference_type diff1 (0);
+            if (it1_size > 0 && it1e_size > 0) {
+                diff1 = it1.index1 () - it1e.index1 ();
+                difference_type size1 = (std::min) (diff1, it1e_size);
+                if (size1 > 0) {
+                    it1e += size1;
+                    it1e_size -= size1;
+                    diff1 -= size1;
+                }
+                size1 = (std::min) (- diff1, it1_size);
+                if (size1 > 0) {
+                    it1_size -= size1;
+                    if (!functor_type::computed) {
+                        while (-- size1 >= 0)   // zeroing
+                            functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
+                    } else {
+                        it1 += size1;
+                    }
+                    diff1 += size1;
+                }
+            }
+            difference_type size1 ((std::min) (it1_size, it1e_size));
+            it1_size -= size1;
+            it1e_size -= size1;
+            while (-- size1 >= 0)
+                functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
+            size1 = it1_size;
+            if (!functor_type::computed) {
+                while (-- size1 >= 0)   // zeroing
+                    functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
+            } else {
+                it1 += size1;
+            }
+            ++ it2, ++ it2e;
+        }
+        size2 = it2_size;
+        if (!functor_type::computed) {
+            while (-- size2 >= 0) { // zeroing
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename M::iterator1 it1 (it2.begin ());
+                typename M::iterator1 it1_end (it2.end ());
+#else
+                typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+                typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+#endif
+                difference_type size1 (it1_end - it1);
+                while (-- size1 >= 0)
+                    functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
+                ++ it2;
+            }
+        } else {
+            it2 += size2;
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        if (! disable_type_check<bool>::value)
+            BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
+#endif
+    }
+    // Sparse row major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, row_major_tag) {
+        typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
+        // R unnecessary, make_conformant not required
+        BOOST_STATIC_ASSERT ((!functor_type::computed));
+        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
+        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
+        typedef typename M::value_type value_type;
+        // Sparse type has no numeric constraints to check
+
+        m.clear ();
+        typename E::const_iterator1 it1e (e ().begin1 ());
+        typename E::const_iterator1 it1e_end (e ().end1 ());
+        while (it1e != it1e_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename E::const_iterator2 it2e (it1e.begin ());
+            typename E::const_iterator2 it2e_end (it1e.end ());
+#else
+            typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
+            typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
+#endif
+            while (it2e != it2e_end) {
+                value_type t (*it2e);
+                if (t != value_type/*zero*/())
+                    m.insert_element (it2e.index1 (), it2e.index2 (), t);
+                ++ it2e;
+            }
+            ++ it1e;
+        }
+    }
+    // Sparse column major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, column_major_tag) {
+        typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
+        // R unnecessary, make_conformant not required
+        BOOST_STATIC_ASSERT ((!functor_type::computed));
+        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
+        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
+        typedef typename M::value_type value_type;
+        // Sparse type has no numeric constraints to check
+
+        m.clear ();
+        typename E::const_iterator2 it2e (e ().begin2 ());
+        typename E::const_iterator2 it2e_end (e ().end2 ());
+        while (it2e != it2e_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename E::const_iterator1 it1e (it2e.begin ());
+            typename E::const_iterator1 it1e_end (it2e.end ());
+#else
+            typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
+            typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
+#endif
+            while (it1e != it1e_end) {
+                value_type t (*it1e);
+                if (t != value_type/*zero*/())
+                    m.insert_element (it1e.index1 (), it1e.index2 (), t);
+                ++ it1e;
+            }
+            ++ it2e;
+        }
+    }
+    // Sparse proxy or functional row major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
+        typedef typename matrix_traits<E>::value_type expr_value_type;
+        typedef F<typename M::iterator2::reference, expr_value_type> functor_type;
+        typedef R conformant_restrict_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+
+        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
+        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
+
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef typename M::value_type value_type;
+        matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
+        indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
+        indexing_matrix_assign<F> (cm, e, row_major_tag ());
+#endif
+        detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
+
+        typename M::iterator1 it1 (m.begin1 ());
+        typename M::iterator1 it1_end (m.end1 ());
+        typename E::const_iterator1 it1e (e ().begin1 ());
+        typename E::const_iterator1 it1e_end (e ().end1 ());
+        while (it1 != it1_end && it1e != it1e_end) {
+            difference_type compare = it1.index1 () - it1e.index1 ();
+            if (compare == 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename M::iterator2 it2 (it1.begin ());
+                typename M::iterator2 it2_end (it1.end ());
+                typename E::const_iterator2 it2e (it1e.begin ());
+                typename E::const_iterator2 it2e_end (it1e.end ());
+#else
+                typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+                typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+                typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
+                typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
+#endif
+                if (it2 != it2_end && it2e != it2e_end) {
+                    size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
+                    while (true) {
+                        difference_type compare2 = it2_index - it2e_index;
+                        if (compare2 == 0) {
+                            functor_type::apply (*it2, *it2e);
+                            ++ it2, ++ it2e;
+                            if (it2 != it2_end && it2e != it2e_end) {
+                                it2_index = it2.index2 ();
+                                it2e_index = it2e.index2 ();
+                            } else
+                                break;
+                        } else if (compare2 < 0) {
+                            if (!functor_type::computed) {
+                                functor_type::apply (*it2, expr_value_type/*zero*/());
+                                ++ it2;
+                            } else
+                                increment (it2, it2_end, - compare2);
+                            if (it2 != it2_end)
+                                it2_index = it2.index2 ();
+                            else
+                                break;
+                        } else if (compare2 > 0) {
+                            increment (it2e, it2e_end, compare2);
+                            if (it2e != it2e_end)
+                                it2e_index = it2e.index2 ();
+                            else
+                                break;
+                        }
+                    }
+                }
+                if (!functor_type::computed) {
+                    while (it2 != it2_end) {    // zeroing
+                        functor_type::apply (*it2, expr_value_type/*zero*/());
+                        ++ it2;
+                    }
+                } else {
+                    it2 = it2_end;
+                }
+                ++ it1, ++ it1e;
+            } else if (compare < 0) {
+                if (!functor_type::computed) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                    typename M::iterator2 it2 (it1.begin ());
+                    typename M::iterator2 it2_end (it1.end ());
+#else
+                    typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+                    typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+#endif
+                    while (it2 != it2_end) {    // zeroing
+                        functor_type::apply (*it2, expr_value_type/*zero*/());
+                        ++ it2;
+                    }
+                    ++ it1;
+                } else {
+                    increment (it1, it1_end, - compare);
+                }
+            } else if (compare > 0) {
+                increment (it1e, it1e_end, compare);
+            }
+        }
+        if (!functor_type::computed) {
+            while (it1 != it1_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename M::iterator2 it2 (it1.begin ());
+                typename M::iterator2 it2_end (it1.end ());
+#else
+                typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+                typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+#endif
+                while (it2 != it2_end) {    // zeroing
+                    functor_type::apply (*it2, expr_value_type/*zero*/());
+                    ++ it2;
+                }
+                ++ it1;
+            }
+        } else {
+            it1 = it1_end;
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        if (! disable_type_check<bool>::value)
+            BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
+#endif
+    }
+    // Sparse proxy or functional column major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
+        typedef typename matrix_traits<E>::value_type expr_value_type;
+        typedef F<typename M::iterator1::reference, expr_value_type> functor_type;
+        typedef R conformant_restrict_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+
+        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
+        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
+
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef typename M::value_type value_type;
+        matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
+        indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
+        indexing_matrix_assign<F> (cm, e, column_major_tag ());
+#endif
+        detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
+
+        typename M::iterator2 it2 (m.begin2 ());
+        typename M::iterator2 it2_end (m.end2 ());
+        typename E::const_iterator2 it2e (e ().begin2 ());
+        typename E::const_iterator2 it2e_end (e ().end2 ());
+        while (it2 != it2_end && it2e != it2e_end) {
+            difference_type compare = it2.index2 () - it2e.index2 ();
+            if (compare == 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename M::iterator1 it1 (it2.begin ());
+                typename M::iterator1 it1_end (it2.end ());
+                typename E::const_iterator1 it1e (it2e.begin ());
+                typename E::const_iterator1 it1e_end (it2e.end ());
+#else
+                typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+                typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+                typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
+                typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
+#endif
+                if (it1 != it1_end && it1e != it1e_end) {
+                    size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
+                    while (true) {
+                        difference_type compare2 = it1_index - it1e_index;
+                        if (compare2 == 0) {
+                            functor_type::apply (*it1, *it1e);
+                            ++ it1, ++ it1e;
+                            if (it1 != it1_end && it1e != it1e_end) {
+                                it1_index = it1.index1 ();
+                                it1e_index = it1e.index1 ();
+                            } else
+                                break;
+                        } else if (compare2 < 0) {
+                            if (!functor_type::computed) {
+                                functor_type::apply (*it1, expr_value_type/*zero*/()); // zeroing
+                                ++ it1;
+                            } else
+                                increment (it1, it1_end, - compare2);
+                            if (it1 != it1_end)
+                                it1_index = it1.index1 ();
+                            else
+                                break;
+                        } else if (compare2 > 0) {
+                            increment (it1e, it1e_end, compare2);
+                            if (it1e != it1e_end)
+                                it1e_index = it1e.index1 ();
+                            else
+                                break;
+                        }
+                    }
+                }
+                if (!functor_type::computed) {
+                    while (it1 != it1_end) {    // zeroing
+                        functor_type::apply (*it1, expr_value_type/*zero*/());
+                        ++ it1;
+                    }
+                } else {
+                    it1 = it1_end;
+                }
+                ++ it2, ++ it2e;
+            } else if (compare < 0) {
+                if (!functor_type::computed) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                    typename M::iterator1 it1 (it2.begin ());
+                    typename M::iterator1 it1_end (it2.end ());
+#else
+                    typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+                    typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+#endif
+                    while (it1 != it1_end) {    // zeroing
+                        functor_type::apply (*it1, expr_value_type/*zero*/());
+                        ++ it1;
+                    }
+                    ++ it2;
+                } else {
+                    increment (it2, it2_end, - compare);
+                }
+            } else if (compare > 0) {
+                increment (it2e, it2e_end, compare);
+            }
+        }
+        if (!functor_type::computed) {
+            while (it2 != it2_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename M::iterator1 it1 (it2.begin ());
+                typename M::iterator1 it1_end (it2.end ());
+#else
+                typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+                typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+#endif
+                while (it1 != it1_end) {    // zeroing
+                    functor_type::apply (*it1, expr_value_type/*zero*/());
+                    ++ it1;
+                }
+                ++ it2;
+            }
+        } else {
+            it2 = it2_end;
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        if (! disable_type_check<bool>::value)
+            BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
+#endif
+    }
+
+    // Dispatcher
+    template<template <class T1, class T2> class F, class M, class E>
+    BOOST_UBLAS_INLINE
+    void matrix_assign (M &m, const matrix_expression<E> &e) {
+        typedef typename matrix_assign_traits<typename M::storage_category,
+                                              F<typename M::reference, typename E::value_type>::computed,
+                                              typename E::const_iterator1::iterator_category,
+                                              typename E::const_iterator2::iterator_category>::storage_category storage_category;
+        // give preference to matrix M's orientation if known
+        typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
+                                          typename E::orientation_category ,
+                                          typename M::orientation_category >::type orientation_category;
+        typedef basic_full<typename M::size_type> unrestricted;
+        matrix_assign<F, unrestricted> (m, e, storage_category (), orientation_category ());
+    }
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    BOOST_UBLAS_INLINE
+    void matrix_assign (M &m, const matrix_expression<E> &e) {
+        typedef R conformant_restrict_type;
+        typedef typename matrix_assign_traits<typename M::storage_category,
+                                              F<typename M::reference, typename E::value_type>::computed,
+                                              typename E::const_iterator1::iterator_category,
+                                              typename E::const_iterator2::iterator_category>::storage_category storage_category;
+        // give preference to matrix M's orientation if known
+        typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
+                                          typename E::orientation_category ,
+                                          typename M::orientation_category >::type orientation_category;
+        matrix_assign<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
+    }
+
+    template<class SC, class RI1, class RI2>
+    struct matrix_swap_traits {
+        typedef SC storage_category;
+    };
+
+    template<>
+    struct matrix_swap_traits<dense_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<>
+    struct matrix_swap_traits<packed_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    // Dense (proxy) row major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, row_major_tag) {
+        typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
+        // R unnecessary, make_conformant not required
+        //typedef typename M::size_type size_type; // gcc is complaining that this is not used, although this is not right
+        typedef typename M::difference_type difference_type;
+        typename M::iterator1 it1 (m.begin1 ());
+        typename E::iterator1 it1e (e ().begin1 ());
+        difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (e ().end1 () - it1e)));
+        while (-- size1 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator2 it2 (it1.begin ());
+            typename E::iterator2 it2e (it1e.begin ());
+            difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (it1e.end () - it2e)));
+#else
+            typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+            typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
+            difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (end (it1e, iterator1_tag ()) - it2e)));
+#endif
+            while (-- size2 >= 0)
+                functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
+            ++ it1, ++ it1e;
+        }
+    }
+    // Dense (proxy) column major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, column_major_tag) {
+        typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
+        // R unnecessary, make_conformant not required
+        // typedef typename M::size_type size_type; // gcc is complaining that this is not used, although this is not right
+        typedef typename M::difference_type difference_type;
+        typename M::iterator2 it2 (m.begin2 ());
+        typename E::iterator2 it2e (e ().begin2 ());
+        difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (e ().end2 () - it2e)));
+        while (-- size2 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator1 it1 (it2.begin ());
+            typename E::iterator1 it1e (it2e.begin ());
+            difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (it2e.end () - it1e)));
+#else
+            typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+            typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
+            difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (end (it2e, iterator2_tag ()) - it1e)));
+#endif
+            while (-- size1 >= 0)
+                functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
+            ++ it2, ++ it2e;
+        }
+    }
+    // Packed (proxy) row major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
+        typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
+        // R unnecessary, make_conformant not required
+        typedef typename M::difference_type difference_type;
+        typename M::iterator1 it1 (m.begin1 ());
+        typename E::iterator1 it1e (e ().begin1 ());
+        difference_type size1 (BOOST_UBLAS_SAME (m.end1 () - it1, e ().end1 () - it1e));
+        while (-- size1 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator2 it2 (it1.begin ());
+            typename E::iterator2 it2e (it1e.begin ());
+            difference_type size2 (BOOST_UBLAS_SAME (it1.end () - it2, it1e.end () - it2e));
+#else
+            typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+            typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
+            difference_type size2 (BOOST_UBLAS_SAME (end (it1, iterator1_tag ()) - it2, end (it1e, iterator1_tag ()) - it2e));
+#endif
+            while (-- size2 >= 0)
+                functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
+            ++ it1, ++ it1e;
+        }
+    }
+    // Packed (proxy) column major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
+        typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
+        // R unnecessary, make_conformant not required
+        typedef typename M::difference_type difference_type;
+        typename M::iterator2 it2 (m.begin2 ());
+        typename E::iterator2 it2e (e ().begin2 ());
+        difference_type size2 (BOOST_UBLAS_SAME (m.end2 () - it2, e ().end2 () - it2e));
+        while (-- size2 >= 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator1 it1 (it2.begin ());
+            typename E::iterator1 it1e (it2e.begin ());
+            difference_type size1 (BOOST_UBLAS_SAME (it2.end () - it1, it2e.end () - it1e));
+#else
+            typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+            typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
+            difference_type size1 (BOOST_UBLAS_SAME (end (it2, iterator2_tag ()) - it1, end (it2e, iterator2_tag ()) - it1e));
+#endif
+            while (-- size1 >= 0)
+                functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
+            ++ it2, ++ it2e;
+        }
+    }
+    // Sparse (proxy) row major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
+        typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
+        typedef R conformant_restrict_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
+        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
+
+        detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
+        // FIXME should be a seperate restriction for E
+        detail::make_conformant (e (), m, row_major_tag (), conformant_restrict_type ());
+
+        typename M::iterator1 it1 (m.begin1 ());
+        typename M::iterator1 it1_end (m.end1 ());
+        typename E::iterator1 it1e (e ().begin1 ());
+        typename E::iterator1 it1e_end (e ().end1 ());
+        while (it1 != it1_end && it1e != it1e_end) {
+            difference_type compare = it1.index1 () - it1e.index1 ();
+            if (compare == 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename M::iterator2 it2 (it1.begin ());
+                typename M::iterator2 it2_end (it1.end ());
+                typename E::iterator2 it2e (it1e.begin ());
+                typename E::iterator2 it2e_end (it1e.end ());
+#else
+                typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+                typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+                typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
+                typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
+#endif
+                if (it2 != it2_end && it2e != it2e_end) {
+                    size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
+                    while (true) {
+                        difference_type compare2 = it2_index - it2e_index;
+                        if (compare2 == 0) {
+                            functor_type::apply (*it2, *it2e);
+                            ++ it2, ++ it2e;
+                            if (it2 != it2_end && it2e != it2e_end) {
+                                it2_index = it2.index2 ();
+                                it2e_index = it2e.index2 ();
+                            } else
+                                break;
+                        } else if (compare2 < 0) {
+                            increment (it2, it2_end, - compare2);
+                            if (it2 != it2_end)
+                                it2_index = it2.index2 ();
+                            else
+                                break;
+                        } else if (compare2 > 0) {
+                            increment (it2e, it2e_end, compare2);
+                            if (it2e != it2e_end)
+                                it2e_index = it2e.index2 ();
+                            else
+                                break;
+                        }
+                    }
+                }
+#if BOOST_UBLAS_TYPE_CHECK
+                increment (it2e, it2e_end);
+                increment (it2, it2_end);
+#endif
+                ++ it1, ++ it1e;
+            } else if (compare < 0) {
+#if BOOST_UBLAS_TYPE_CHECK
+                while (it1.index1 () < it1e.index1 ()) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                    typename M::iterator2 it2 (it1.begin ());
+                    typename M::iterator2 it2_end (it1.end ());
+#else
+                    typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+                    typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+#endif
+                    increment (it2, it2_end);
+                    ++ it1;
+                }
+#else
+                increment (it1, it1_end, - compare);
+#endif
+            } else if (compare > 0) {
+#if BOOST_UBLAS_TYPE_CHECK
+                while (it1e.index1 () < it1.index1 ()) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                    typename E::iterator2 it2e (it1e.begin ());
+                    typename E::iterator2 it2e_end (it1e.end ());
+#else
+                    typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
+                    typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
+#endif
+                    increment (it2e, it2e_end);
+                    ++ it1e;
+                }
+#else
+                increment (it1e, it1e_end, compare);
+#endif
+            }
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        while (it1e != it1e_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename E::iterator2 it2e (it1e.begin ());
+            typename E::iterator2 it2e_end (it1e.end ());
+#else
+            typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
+            typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
+#endif
+            increment (it2e, it2e_end);
+            ++ it1e;
+        }
+        while (it1 != it1_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator2 it2 (it1.begin ());
+            typename M::iterator2 it2_end (it1.end ());
+#else
+            typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
+            typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
+#endif
+            increment (it2, it2_end);
+            ++ it1;
+        }
+#endif
+    }
+    // Sparse (proxy) column major case
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
+        typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
+        typedef R conformant_restrict_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+
+        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
+        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
+
+        detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
+        // FIXME should be a seperate restriction for E
+        detail::make_conformant (e (), m, column_major_tag (), conformant_restrict_type ());
+
+        typename M::iterator2 it2 (m.begin2 ());
+        typename M::iterator2 it2_end (m.end2 ());
+        typename E::iterator2 it2e (e ().begin2 ());
+        typename E::iterator2 it2e_end (e ().end2 ());
+        while (it2 != it2_end && it2e != it2e_end) {
+            difference_type compare = it2.index2 () - it2e.index2 ();
+            if (compare == 0) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                typename M::iterator1 it1 (it2.begin ());
+                typename M::iterator1 it1_end (it2.end ());
+                typename E::iterator1 it1e (it2e.begin ());
+                typename E::iterator1 it1e_end (it2e.end ());
+#else
+                typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+                typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+                typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
+                typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
+#endif
+                if (it1 != it1_end && it1e != it1e_end) {
+                    size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
+                    while (true) {
+                        difference_type compare2 = it1_index - it1e_index;
+                        if (compare2 == 0) {
+                            functor_type::apply (*it1, *it1e);
+                            ++ it1, ++ it1e;
+                            if (it1 != it1_end && it1e != it1e_end) {
+                                it1_index = it1.index1 ();
+                                it1e_index = it1e.index1 ();
+                            } else
+                                break;
+                        }  else if (compare2 < 0) {
+                            increment (it1, it1_end, - compare2);
+                            if (it1 != it1_end)
+                                it1_index = it1.index1 ();
+                            else
+                                break;
+                        } else if (compare2 > 0) {
+                            increment (it1e, it1e_end, compare2);
+                            if (it1e != it1e_end)
+                                it1e_index = it1e.index1 ();
+                            else
+                                break;
+                        }
+                    }
+                }
+#if BOOST_UBLAS_TYPE_CHECK
+                increment (it1e, it1e_end);
+                increment (it1, it1_end);
+#endif
+                ++ it2, ++ it2e;
+            } else if (compare < 0) {
+#if BOOST_UBLAS_TYPE_CHECK
+                while (it2.index2 () < it2e.index2 ()) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                    typename M::iterator1 it1 (it2.begin ());
+                    typename M::iterator1 it1_end (it2.end ());
+#else
+                    typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+                    typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+#endif
+                    increment (it1, it1_end);
+                    ++ it2;
+                }
+#else
+                increment (it2, it2_end, - compare);
+#endif
+            } else if (compare > 0) {
+#if BOOST_UBLAS_TYPE_CHECK
+                while (it2e.index2 () < it2.index2 ()) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                    typename E::iterator1 it1e (it2e.begin ());
+                    typename E::iterator1 it1e_end (it2e.end ());
+#else
+                    typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
+                    typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
+#endif
+                    increment (it1e, it1e_end);
+                    ++ it2e;
+                }
+#else
+                increment (it2e, it2e_end, compare);
+#endif
+            }
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        while (it2e != it2e_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename E::iterator1 it1e (it2e.begin ());
+            typename E::iterator1 it1e_end (it2e.end ());
+#else
+            typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
+            typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
+#endif
+            increment (it1e, it1e_end);
+            ++ it2e;
+        }
+        while (it2 != it2_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename M::iterator1 it1 (it2.begin ());
+            typename M::iterator1 it1_end (it2.end ());
+#else
+            typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
+            typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
+#endif
+            increment (it1, it1_end);
+            ++ it2;
+        }
+#endif
+    }
+
+    // Dispatcher
+    template<template <class T1, class T2> class F, class M, class E>
+    BOOST_UBLAS_INLINE
+    void matrix_swap (M &m, matrix_expression<E> &e) {
+        typedef typename matrix_swap_traits<typename M::storage_category,
+                                            typename E::const_iterator1::iterator_category,
+                                            typename E::const_iterator2::iterator_category>::storage_category storage_category;
+        // give preference to matrix M's orientation if known
+        typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
+                                          typename E::orientation_category ,
+                                          typename M::orientation_category >::type orientation_category;
+        typedef basic_full<typename M::size_type> unrestricted;
+        matrix_swap<F, unrestricted> (m, e, storage_category (), orientation_category ());
+    }
+    template<template <class T1, class T2> class F, class R, class M, class E>
+    BOOST_UBLAS_INLINE
+    void matrix_swap (M &m, matrix_expression<E> &e) {
+        typedef R conformant_restrict_type;
+        typedef typename matrix_swap_traits<typename M::storage_category,
+                                            typename E::const_iterator1::iterator_category,
+                                            typename E::const_iterator2::iterator_category>::storage_category storage_category;
+        // give preference to matrix M's orientation if known
+        typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
+                                          typename E::orientation_category ,
+                                          typename M::orientation_category >::type orientation_category;
+        matrix_swap<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/detail/raw.hpp b/include/boost/numeric/ublas/detail/raw.hpp
new file mode 100644
index 0000000..c36c8b0
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/raw.hpp
@@ -0,0 +1,878 @@
+//
+//  Copyright (c) 2002-2003
+//  Toon Knapen, Kresimir Fresl, Joerg Walter
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+
+#ifndef _BOOST_UBLAS_RAW_
+#define _BOOST_UBLAS_RAW_
+
+namespace boost { namespace numeric { namespace ublas { namespace raw {
+
+    // We need data_const() mostly due to MSVC 6.0.
+    // But how shall we write portable code otherwise?
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    int size( const V &v ) ;
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    int size( const vector_reference<V> &v ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int size1( const M &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int size2( const M &m ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int size1( const matrix_reference<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int size2( const matrix_reference<M> &m ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int leading_dimension( const M &m, row_major_tag ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int leading_dimension( const M &m, column_major_tag ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int leading_dimension( const M &m ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int leading_dimension( const matrix_reference<M> &m ) ;
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    int stride( const V &v ) ;
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    int stride( const vector_range<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    int stride( const vector_slice<V> &v ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride( const matrix_row<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride( const matrix_column<M> &v ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride1( const M &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride2( const M &m ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride1( const matrix_reference<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride2( const matrix_reference<M> &m ) ;
+
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    int stride1( const c_matrix<T, M, N> &m ) ;
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    int stride2( const c_matrix<T, M, N> &m ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride1( const matrix_range<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride1( const matrix_slice<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride2( const matrix_range<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride2( const matrix_slice<M> &m ) ;
+
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::array_type::const_pointer data( const MV &mv ) ;
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::array_type::const_pointer data_const( const MV &mv ) ;
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::pointer data( MV &mv ) ;
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data( const vector_reference<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data_const( const vector_reference<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer data( vector_reference<V> &v ) ;
+
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::array_type::array_type::const_pointer data( const c_vector<T, N> &v ) ;
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::array_type::array_type::const_pointer data_const( const c_vector<T, N> &v ) ;
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::pointer data( c_vector<T, N> &v ) ;
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data( const vector_range<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data( const vector_slice<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data_const( const vector_range<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data_const( const vector_slice<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer data( vector_range<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer data( vector_slice<V> &v ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer data( const matrix_reference<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer data_const( const matrix_reference<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer data( matrix_reference<M> &m ) ;
+
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::array_type::array_type::const_pointer data( const c_matrix<T, M, N> &m ) ;
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::array_type::array_type::const_pointer data_const( const c_matrix<T, M, N> &m ) ;
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::pointer data( c_matrix<T, M, N> &m ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer data( const matrix_row<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer data( const matrix_column<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer data_const( const matrix_row<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer data_const( const matrix_column<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer data( matrix_row<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer data( matrix_column<M> &v ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer data( const matrix_range<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer data( const matrix_slice<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer data_const( const matrix_range<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer data_const( const matrix_slice<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer data( matrix_range<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer data( matrix_slice<M> &m ) ;
+
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::array_type::const_pointer base( const MV &mv ) ;
+
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::array_type::const_pointer base_const( const MV &mv ) ;
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::pointer base( MV &mv ) ;
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer base( const vector_reference<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer base_const( const vector_reference<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer base( vector_reference<V> &v ) ;
+
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::array_type::array_type::const_pointer base( const c_vector<T, N> &v ) ;
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::array_type::array_type::const_pointer base_const( const c_vector<T, N> &v ) ;
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::pointer base( c_vector<T, N> &v ) ;
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer base( const vector_range<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer base( const vector_slice<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer base_const( const vector_range<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer base_const( const vector_slice<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer base( vector_range<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer base( vector_slice<V> &v ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer base( const matrix_reference<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer base_const( const matrix_reference<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer base( matrix_reference<M> &m ) ;
+
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::array_type::array_type::const_pointer base( const c_matrix<T, M, N> &m ) ;
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::array_type::array_type::const_pointer base_const( const c_matrix<T, M, N> &m ) ;
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::pointer base( c_matrix<T, M, N> &m ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer base( const matrix_row<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer base( const matrix_column<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer base_const( const matrix_row<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer base_const( const matrix_column<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer base( matrix_row<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer base( matrix_column<M> &v ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer base( const matrix_range<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer base( const matrix_slice<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer base_const( const matrix_range<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::array_type::const_pointer base_const( const matrix_slice<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer base( matrix_range<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer base( matrix_slice<M> &m ) ;
+
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::size_type start( const MV &mv ) ;
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::size_type start( const vector_range<V> &v ) ;
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::size_type start( const vector_slice<V> &v ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::size_type start( const matrix_row<M> &v ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::size_type start( const matrix_column<M> &v ) ;
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::size_type start( const matrix_range<M> &m ) ;
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::size_type start( const matrix_slice<M> &m ) ;
+
+
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    int size( const V &v ) {
+        return v.size() ;
+    }
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    int size( const vector_reference<V> &v ) {
+        return size( v ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int size1( const M &m ) {
+        return m.size1() ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int size2( const M &m ) {
+        return m.size2() ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int size1( const matrix_reference<M> &m ) {
+        return size1( m.expression() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int size2( const matrix_reference<M> &m ) {
+        return size2( m.expression() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int leading_dimension( const M &m, row_major_tag ) {
+        return m.size2() ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int leading_dimension( const M &m, column_major_tag ) {
+        return m.size1() ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int leading_dimension( const M &m ) {
+        return leading_dimension( m, typename M::orientation_category() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int leading_dimension( const matrix_reference<M> &m ) {
+        return leading_dimension( m.expression() ) ;
+    }
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    int stride( const V &v ) {
+        return 1 ;
+    }
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    int stride( const vector_range<V> &v ) {
+        return stride( v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    int stride( const vector_slice<V> &v ) {
+        return v.stride() * stride( v.data() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride( const matrix_row<M> &v ) {
+        return stride2( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride( const matrix_column<M> &v ) {
+        return stride1( v.data() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride1( const M &m ) {
+        typedef typename M::functor_type functor_type;
+        return functor_type::one1( m.size1(), m.size2() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride2( const M &m ) {
+        typedef typename M::functor_type functor_type;
+        return functor_type::one2( m.size1(), m.size2() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride1( const matrix_reference<M> &m ) {
+        return stride1( m.expression() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride2( const matrix_reference<M> &m ) {
+        return stride2( m.expression() ) ;
+    }
+
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    int stride1( const c_matrix<T, M, N> &m ) {
+        return N ;
+    }
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    int stride2( const c_matrix<T, M, N> &m ) {
+        return 1 ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride1( const matrix_range<M> &m ) {
+        return stride1( m.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride1( const matrix_slice<M> &m ) {
+        return m.stride1() * stride1( m.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride2( const matrix_range<M> &m ) {
+        return stride2( m.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    int stride2( const matrix_slice<M> &m ) {
+        return m.stride2() * stride2( m.data() ) ;
+    }
+
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::array_type::array_type::const_pointer data( const MV &mv ) {
+        return &mv.data().begin()[0] ;
+    }
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::array_type::const_pointer data_const( const MV &mv ) {
+        return &mv.data().begin()[0] ;
+    }
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::pointer data( MV &mv ) {
+        return &mv.data().begin()[0] ;
+    }
+
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data( const vector_reference<V> &v ) {
+        return data( v.expression () ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data_const( const vector_reference<V> &v ) {
+        return data_const( v.expression () ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer data( vector_reference<V> &v ) {
+        return data( v.expression () ) ;
+    }
+
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::array_type::array_type::const_pointer data( const c_vector<T, N> &v ) {
+        return v.data() ;
+    }
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::array_type::array_type::const_pointer data_const( const c_vector<T, N> &v ) {
+        return v.data() ;
+    }
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::pointer data( c_vector<T, N> &v ) {
+        return v.data() ;
+    }
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data( const vector_range<V> &v ) {
+        return data( v.data() ) + v.start() * stride (v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data( const vector_slice<V> &v ) {
+        return data( v.data() ) + v.start() * stride (v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::array_type::const_pointer data_const( const vector_range<V> &v ) {
+        return data_const( v.data() ) + v.start() * stride (v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::const_pointer data_const( const vector_slice<V> &v ) {
+        return data_const( v.data() ) + v.start() * stride (v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer data( vector_range<V> &v ) {
+        return data( v.data() ) + v.start() * stride (v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer data( vector_slice<V> &v ) {
+        return data( v.data() ) + v.start() * stride (v.data() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer data( const matrix_reference<M> &m ) {
+        return data( m.expression () ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer data_const( const matrix_reference<M> &m ) {
+        return data_const( m.expression () ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer data( matrix_reference<M> &m ) {
+        return data( m.expression () ) ;
+    }
+
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::array_type::const_pointer data( const c_matrix<T, M, N> &m ) {
+        return m.data() ;
+    }
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::array_type::const_pointer data_const( const c_matrix<T, M, N> &m ) {
+        return m.data() ;
+    }
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::pointer data( c_matrix<T, M, N> &m ) {
+        return m.data() ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer data( const matrix_row<M> &v ) {
+        return data( v.data() ) + v.index() * stride1( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer data( const matrix_column<M> &v ) {
+        return data( v.data() ) + v.index() * stride2( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer data_const( const matrix_row<M> &v ) {
+        return data_const( v.data() ) + v.index() * stride1( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer data_const( const matrix_column<M> &v ) {
+        return data_const( v.data() ) + v.index() * stride2( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer data( matrix_row<M> &v ) {
+        return data( v.data() ) + v.index() * stride1( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer data( matrix_column<M> &v ) {
+        return data( v.data() ) + v.index() * stride2( v.data() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer data( const matrix_range<M> &m ) {
+        return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer data( const matrix_slice<M> &m ) {
+        return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer data_const( const matrix_range<M> &m ) {
+        return data_const( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer data_const( const matrix_slice<M> &m ) {
+        return data_const( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer data( matrix_range<M> &m ) {
+        return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer data( matrix_slice<M> &m ) {
+        return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
+    }
+
+
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::const_pointer base( const MV &mv ) {
+        return &mv.data().begin()[0] ;
+    }
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::const_pointer base_const( const MV &mv ) {
+        return &mv.data().begin()[0] ;
+    }
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::array_type::pointer base( MV &mv ) {
+        return &mv.data().begin()[0] ;
+    }
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::const_pointer base( const vector_reference<V> &v ) {
+        return base( v.expression () ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::const_pointer base_const( const vector_reference<V> &v ) {
+        return base_const( v.expression () ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer base( vector_reference<V> &v ) {
+        return base( v.expression () ) ;
+    }
+
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::array_type::const_pointer base( const c_vector<T, N> &v ) {
+        return v.data() ;
+    }
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::array_type::const_pointer base_const( const c_vector<T, N> &v ) {
+        return v.data() ;
+    }
+    template < typename T, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_vector<T, N>::pointer base( c_vector<T, N> &v ) {
+        return v.data() ;
+    }
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::const_pointer base( const vector_range<V> &v ) {
+        return base( v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::const_pointer base( const vector_slice<V> &v ) {
+        return base( v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::const_pointer base_const( const vector_range<V> &v ) {
+        return base_const( v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::const_pointer base_const( const vector_slice<V> &v ) {
+        return base_const( v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer base( vector_range<V> &v ) {
+        return base( v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::array_type::pointer base( vector_slice<V> &v ) {
+        return base( v.data() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer base( const matrix_reference<M> &m ) {
+        return base( m.expression () ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer base_const( const matrix_reference<M> &m ) {
+        return base_const( m.expression () ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer base( matrix_reference<M> &m ) {
+        return base( m.expression () ) ;
+    }
+
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::array_type::const_pointer base( const c_matrix<T, M, N> &m ) {
+        return m.data() ;
+    }
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::array_type::const_pointer base_const( const c_matrix<T, M, N> &m ) {
+        return m.data() ;
+    }
+    template < typename T, std::size_t M, std::size_t N >
+    BOOST_UBLAS_INLINE
+    typename c_matrix<T, M, N>::pointer base( c_matrix<T, M, N> &m ) {
+        return m.data() ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer base( const matrix_row<M> &v ) {
+        return base( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer base( const matrix_column<M> &v ) {
+        return base( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer base_const( const matrix_row<M> &v ) {
+        return base_const( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer base_const( const matrix_column<M> &v ) {
+        return base_const( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer base( matrix_row<M> &v ) {
+        return base( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer base( matrix_column<M> &v ) {
+        return base( v.data() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer base( const matrix_range<M> &m ) {
+        return base( m.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer base( const matrix_slice<M> &m ) {
+        return base( m.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer base_const( const matrix_range<M> &m ) {
+        return base_const( m.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::const_pointer base_const( const matrix_slice<M> &m ) {
+        return base_const( m.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer base( matrix_range<M> &m ) {
+        return base( m.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::array_type::pointer base( matrix_slice<M> &m ) {
+        return base( m.data() ) ;
+    }
+
+    template < typename MV >
+    BOOST_UBLAS_INLINE
+    typename MV::size_type start( const MV &mv ) {
+        return 0 ;
+    }
+
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::size_type start( const vector_range<V> &v ) {
+        return v.start() * stride (v.data() ) ;
+    }
+    template < typename V >
+    BOOST_UBLAS_INLINE
+    typename V::size_type start( const vector_slice<V> &v ) {
+        return v.start() * stride (v.data() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::size_type start( const matrix_row<M> &v ) {
+        return v.index() * stride1( v.data() ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::size_type start( const matrix_column<M> &v ) {
+        return v.index() * stride2( v.data() ) ;
+    }
+
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::size_type start( const matrix_range<M> &m ) {
+        return m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
+    }
+    template < typename M >
+    BOOST_UBLAS_INLINE
+    typename M::size_type start( const matrix_slice<M> &m ) {
+        return m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
+    }
+
+}}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/detail/returntype_deduction.hpp b/include/boost/numeric/ublas/detail/returntype_deduction.hpp
new file mode 100644
index 0000000..030d1f6
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/returntype_deduction.hpp
@@ -0,0 +1,174 @@
+/*
+ *  Copyright (c) 2001-2003 Joel de Guzman
+ *
+ *  Use, modification and distribution is subject to the Boost Software
+ *  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ *    http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef _BOOST_UBLAS_NUMERICTYPE_DEDUCTION_
+#define _BOOST_UBLAS_NUMERICTYPE_DEDUCTION_
+
+// See original in boost-sandbox/boost/utility/type_deduction.hpp for comments
+
+#include <boost/mpl/vector/vector20.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace numeric { namespace ublas {
+
+struct error_cant_deduce_type {};
+
+  namespace type_deduction_detail
+  {
+    typedef char(&bool_value_type)[1];
+    typedef char(&float_value_type)[2];
+    typedef char(&double_value_type)[3];
+    typedef char(&long_double_value_type)[4];
+    typedef char(&char_value_type)[5];
+    typedef char(&schar_value_type)[6];
+    typedef char(&uchar_value_type)[7];
+    typedef char(&short_value_type)[8];
+    typedef char(&ushort_value_type)[9];
+    typedef char(&int_value_type)[10];
+    typedef char(&uint_value_type)[11];
+    typedef char(&long_value_type)[12];
+    typedef char(&ulong_value_type)[13];
+    
+    typedef char(&x_value_type)[14];
+    typedef char(&y_value_type)[15];
+
+    typedef char(&cant_deduce_type)[16];
+
+    template <typename T, typename PlainT = typename remove_cv<T>::type>
+    struct is_basic
+        : mpl::or_<
+          typename mpl::or_<
+              is_same<PlainT, bool>
+            , is_same<PlainT, float>
+            , is_same<PlainT, double>
+            , is_same<PlainT, long double>
+          > ::type,
+          typename mpl::or_<
+              is_same<PlainT, char>
+            , is_same<PlainT, signed char>
+            , is_same<PlainT, unsigned char>
+            , is_same<PlainT, short>
+            , is_same<PlainT, unsigned short>
+            > ::type,
+          typename mpl::or_<
+              is_same<PlainT, int>
+            , is_same<PlainT, unsigned int>
+            , is_same<PlainT, long>
+            , is_same<PlainT, unsigned long>
+            > ::type
+        > {};
+
+    struct asymmetric;
+
+    template <typename X, typename Y>
+    cant_deduce_type
+    test(...); // The black hole !!!
+
+    template <typename X, typename Y>
+    bool_value_type
+    test(bool const&);
+
+    template <typename X, typename Y>
+    float_value_type
+    test(float const&);
+    
+    template <typename X, typename Y>
+    double_value_type
+    test(double const&);
+
+    template <typename X, typename Y>
+    long_double_value_type
+    test(long double const&);
+
+    template <typename X, typename Y>
+    char_value_type
+    test(char const&);
+
+    template <typename X, typename Y>
+    schar_value_type
+    test(signed char const&);
+
+    template <typename X, typename Y>
+    uchar_value_type
+    test(unsigned char const&);
+
+    template <typename X, typename Y>
+    short_value_type
+    test(short const&);
+
+    template <typename X, typename Y>
+    ushort_value_type
+    test(unsigned short const&);
+
+    template <typename X, typename Y>
+    int_value_type
+    test(int const&);
+
+    template <typename X, typename Y>
+    uint_value_type
+    test(unsigned int const&);
+
+    template <typename X, typename Y>
+    long_value_type
+    test(long const&);
+
+    template <typename X, typename Y>
+    ulong_value_type
+    test(unsigned long const&);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        is_basic<X>, x_value_type
+    >::type
+    test(X const&);
+
+    template <typename X, typename Y>
+    typename disable_if<
+        mpl::or_<
+            is_basic<Y>
+          , is_same<Y, asymmetric>
+          , is_same<const X, const Y>
+        >
+      , y_value_type
+    >::type
+    test(Y const&);
+
+    template <typename X, typename Y>
+    struct base_result_of
+    {
+        typedef typename remove_cv<X>::type x_type;
+        typedef typename remove_cv<Y>::type y_type;
+
+        typedef mpl::vector16<
+            mpl::identity<bool>
+          , mpl::identity<float>
+          , mpl::identity<double>
+          , mpl::identity<long double>
+          , mpl::identity<char>
+          , mpl::identity<signed char>
+          , mpl::identity<unsigned char>
+          , mpl::identity<short>
+          , mpl::identity<unsigned short>
+          , mpl::identity<int>
+          , mpl::identity<unsigned int>
+          , mpl::identity<long>
+          , mpl::identity<unsigned long>
+          , mpl::identity<x_type>
+          , mpl::identity<y_type>
+          , mpl::identity<error_cant_deduce_type>
+        >
+        types;
+    };
+
+}}} } // namespace boost::numeric::ublas ::type_deduction_detail
+
+#endif
diff --git a/include/boost/numeric/ublas/detail/temporary.hpp b/include/boost/numeric/ublas/detail/temporary.hpp
new file mode 100644
index 0000000..c2ae468
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/temporary.hpp
@@ -0,0 +1,33 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_TEMPORARY_
+#define _BOOST_UBLAS_TEMPORARY_
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+/// For the creation of temporary vectors in the assignment of proxies
+template <class M>
+struct vector_temporary_traits {
+   typedef typename M::vector_temporary_type type ;
+};
+
+/// For the creation of temporary vectors in the assignment of proxies
+template <class M>
+struct matrix_temporary_traits {
+   typedef typename M::matrix_temporary_type type ;
+};
+
+} } }
+
+#endif
diff --git a/include/boost/numeric/ublas/detail/vector_assign.hpp b/include/boost/numeric/ublas/detail/vector_assign.hpp
new file mode 100644
index 0000000..e612876
--- /dev/null
+++ b/include/boost/numeric/ublas/detail/vector_assign.hpp
@@ -0,0 +1,570 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_VECTOR_ASSIGN_
+#define _BOOST_UBLAS_VECTOR_ASSIGN_
+
+#include <boost/numeric/ublas/functional.hpp> // scalar_assign
+// Required for make_conformant storage
+#include <vector>
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+namespace detail {
+
+    // 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);
+    }
+
+
+    // Make sparse proxies conformant
+    template<class V, class E>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void make_conformant (V &v, const vector_expression<E> &e) {
+        BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
+        typedef typename V::size_type size_type;
+        typedef typename V::difference_type difference_type;
+        typedef typename V::value_type value_type;
+        // FIXME unbounded_array with push_back maybe better
+        std::vector<size_type> index;
+        typename V::iterator it (v.begin ());
+        typename V::iterator it_end (v.end ());
+        typename E::const_iterator ite (e ().begin ());
+        typename E::const_iterator ite_end (e ().end ());
+        if (it != it_end && ite != ite_end) {
+            size_type it_index = it.index (), ite_index = ite.index ();
+            while (true) {
+                difference_type compare = it_index - ite_index;
+                if (compare == 0) {
+                    ++ it, ++ ite;
+                    if (it != it_end && ite != ite_end) {
+                        it_index = it.index ();
+                        ite_index = ite.index ();
+                    } else
+                        break;
+                } else if (compare < 0) {
+                    increment (it, it_end, - compare);
+                    if (it != it_end)
+                        it_index = it.index ();
+                    else
+                        break;
+                } else if (compare > 0) {
+                    if (*ite != value_type/*zero*/())
+                        index.push_back (ite.index ());
+                    ++ ite;
+                    if (ite != ite_end)
+                        ite_index = ite.index ();
+                    else
+                        break;
+                }
+            }
+        }
+
+        while (ite != ite_end) {
+            if (*ite != value_type/*zero*/())
+                index.push_back (ite.index ());
+            ++ ite;
+        }
+        for (size_type k = 0; k < index.size (); ++ k)
+            v (index [k]) = value_type/*zero*/();
+    }
+
+}//namespace detail
+
+
+    // Explicitly iterating
+    template<template <class T1, class T2> class F, class V, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void iterating_vector_assign_scalar (V &v, const T &t) {
+        typedef F<typename V::iterator::reference, T> functor_type;
+        typedef typename V::difference_type difference_type;
+        difference_type size (v.size ());
+        typename V::iterator it (v.begin ());
+        BOOST_UBLAS_CHECK (v.end () - it == size, bad_size ());
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+        while (-- size >= 0)
+            functor_type::apply (*it, t), ++ it;
+#else
+        DD (size, 4, r, (functor_type::apply (*it, t), ++ it));
+#endif
+    }
+    // Explicitly case
+    template<template <class T1, class T2> class F, class V, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void indexing_vector_assign_scalar (V &v, const T &t) {
+        typedef F<typename V::reference, T> functor_type;
+        typedef typename V::size_type size_type;
+        size_type size (v.size ());
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+        for (size_type i = 0; i < size; ++ i)
+            functor_type::apply (v (i), t);
+#else
+        size_type i (0);
+        DD (size, 4, r, (functor_type::apply (v (i), t), ++ i));
+#endif
+    }
+
+    // Dense (proxy) case
+    template<template <class T1, class T2> class F, class V, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void vector_assign_scalar (V &v, const T &t, dense_proxy_tag) {
+#ifdef BOOST_UBLAS_USE_INDEXING
+        indexing_vector_assign_scalar<F> (v, t);
+#elif BOOST_UBLAS_USE_ITERATING
+        iterating_vector_assign_scalar<F> (v, t);
+#else
+        typedef typename V::size_type size_type;
+        size_type size (v.size ());
+        if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
+            iterating_vector_assign_scalar<F> (v, t);
+        else
+            indexing_vector_assign_scalar<F> (v, t);
+#endif
+    }
+    // Packed (proxy) case
+    template<template <class T1, class T2> class F, class V, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void vector_assign_scalar (V &v, const T &t, packed_proxy_tag) {
+        typedef F<typename V::iterator::reference, T> functor_type;
+        typedef typename V::difference_type difference_type;
+        typename V::iterator it (v.begin ());
+        difference_type size (v.end () - it);
+        while (-- size >= 0)
+            functor_type::apply (*it, t), ++ it;
+    }
+    // Sparse (proxy) case
+    template<template <class T1, class T2> class F, class V, class T>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    void vector_assign_scalar (V &v, const T &t, sparse_proxy_tag) {
+        typedef F<typename V::iterator::reference, T> functor_type;
+        typename V::iterator it (v.begin ());
+        typename V::iterator it_end (v.end ());
+        while (it != it_end)
+            functor_type::apply (*it, t), ++ it;
+    }
+
+    // Dispatcher
+    template<template <class T1, class T2> class F, class V, class T>
+    BOOST_UBLAS_INLINE
+    void vector_assign_scalar (V &v, const T &t) {
+        typedef typename V::storage_category storage_category;
+        vector_assign_scalar<F> (v, t, storage_category ());
+    }
+
+    template<class SC, bool COMPUTED, class RI>
+    struct vector_assign_traits {
+        typedef SC storage_category;
+    };
+
+    template<bool COMPUTED>
+    struct vector_assign_traits<dense_tag, COMPUTED, packed_random_access_iterator_tag> {
+        typedef packed_tag storage_category;
+    };
+    template<>
+    struct vector_assign_traits<dense_tag, false, sparse_bidirectional_iterator_tag> {
+        typedef sparse_tag storage_category;
+    };
+    template<>
+    struct vector_assign_traits<dense_tag, true, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<bool COMPUTED>
+    struct vector_assign_traits<dense_proxy_tag, COMPUTED, packed_random_access_iterator_tag> {
+        typedef packed_proxy_tag storage_category;
+    };
+    template<>
+    struct vector_assign_traits<dense_proxy_tag, false, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+    template<>
+    struct vector_assign_traits<dense_proxy_tag, true, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<>
+    struct vector_assign_traits<packed_tag, false, sparse_bidirectional_iterator_tag> {
+        typedef sparse_tag storage_category;
+    };
+    template<>
+    struct vector_assign_traits<packed_tag, true, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<bool COMPUTED>
+    struct vector_assign_traits<packed_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<>
+    struct vector_assign_traits<sparse_tag, true, dense_random_access_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+    template<>
+    struct vector_assign_traits<sparse_tag, true, packed_random_access_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+    template<>
+    struct vector_assign_traits<sparse_tag, true, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    // Explicitly iterating
+    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 iterating_vector_assign (V &v, const vector_expression<E> &e) {
+        typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
+        typedef typename V::difference_type difference_type;
+        difference_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
+        typename V::iterator it (v.begin ());
+        BOOST_UBLAS_CHECK (v.end () - it == size, bad_size ());
+        typename E::const_iterator ite (e ().begin ());
+        BOOST_UBLAS_CHECK (e ().end () - ite == size, bad_size ());
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+        while (-- size >= 0)
+            functor_type::apply (*it, *ite), ++ it, ++ ite;
+#else
+        DD (size, 2, r, (functor_type::apply (*it, *ite), ++ it, ++ ite));
+#endif
+    }
+    // Explicitly indexing
+    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 indexing_vector_assign (V &v, const vector_expression<E> &e) {
+        typedef F<typename V::reference, typename E::value_type> functor_type;
+        typedef typename V::size_type size_type;
+        size_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+        for (size_type i = 0; i < size; ++ i)
+            functor_type::apply (v (i), e () (i));
+#else
+        size_type i (0);
+        DD (size, 2, r, (functor_type::apply (v (i), e () (i)), ++ i));
+#endif
+    }
+
+    // Dense (proxy) case
+    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, dense_proxy_tag) {
+#ifdef BOOST_UBLAS_USE_INDEXING
+        indexing_vector_assign<F> (v, e);
+#elif BOOST_UBLAS_USE_ITERATING
+        iterating_vector_assign<F> (v, e);
+#else
+        typedef typename V::size_type size_type;
+        size_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
+        if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
+            iterating_vector_assign<F> (v, e);
+        else
+            indexing_vector_assign<F> (v, e);
+#endif
+    }
+    // Packed (proxy) case
+    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, packed_proxy_tag) {
+        BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
+        typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
+        typedef typename V::difference_type difference_type;
+        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
+        typename V::iterator it (v.begin ());
+        typename V::iterator it_end (v.end ());
+        typename E::const_iterator ite (e ().begin ());
+        typename E::const_iterator ite_end (e ().end ());
+        difference_type it_size (it_end - it);
+        difference_type ite_size (ite_end - ite);
+        if (it_size > 0 && ite_size > 0) {
+            difference_type size ((std::min) (difference_type (it.index () - ite.index ()), ite_size));
+            if (size > 0) {
+                ite += size;
+                ite_size -= size;
+            }
+        }
+        if (it_size > 0 && ite_size > 0) {
+            difference_type size ((std::min) (difference_type (ite.index () - it.index ()), it_size));
+            if (size > 0) {
+                it_size -= size;
+                if (!functor_type::computed) {
+                    while (-- size >= 0)    // zeroing
+                        functor_type::apply (*it, value_type/*zero*/()), ++ it;
+                } else {
+                    it += size;
+                }
+            }
+        }
+        difference_type size ((std::min) (it_size, ite_size));
+        it_size -= size;
+        ite_size -= size;
+        while (-- size >= 0)
+            functor_type::apply (*it, *ite), ++ it, ++ ite;
+        size = it_size;
+        if (!functor_type::computed) {
+            while (-- size >= 0)    // zeroing
+                functor_type::apply (*it, value_type/*zero*/()), ++ it;
+        } else {
+            it += size;
+        }
+#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
+    }
+    // Sparse case
+    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
+    }
+    // Sparse proxy or functional case
+    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_proxy_tag) {
+        BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
+        typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::difference_type difference_type;
+        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
+        detail::make_conformant (v, e);
+
+        typename V::iterator it (v.begin ());
+        typename V::iterator it_end (v.end ());
+        typename E::const_iterator ite (e ().begin ());
+        typename E::const_iterator ite_end (e ().end ());
+        if (it != it_end && ite != ite_end) {
+            size_type it_index = it.index (), ite_index = ite.index ();
+            while (true) {
+                difference_type compare = it_index - ite_index;
+                if (compare == 0) {
+                    functor_type::apply (*it, *ite);
+                    ++ it, ++ ite;
+                    if (it != it_end && ite != ite_end) {
+                        it_index = it.index ();
+                        ite_index = ite.index ();
+                    } else
+                        break;
+                } else if (compare < 0) {
+                    if (!functor_type::computed) {
+                        functor_type::apply (*it, value_type/*zero*/());
+                        ++ it;
+                    } else
+                        increment (it, it_end, - compare);
+                    if (it != it_end)
+                        it_index = it.index ();
+                    else
+                        break;
+                } else if (compare > 0) {
+                    increment (ite, ite_end, compare);
+                    if (ite != ite_end)
+                        ite_index = ite.index ();
+                    else
+                        break;
+                }
+            }
+        }
+
+        if (!functor_type::computed) {
+            while (it != it_end) {  // zeroing
+                functor_type::apply (*it, value_type/*zero*/());
+                ++ it;
+            }
+        } else {
+            it = it_end;
+        }
+#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
+    }
+
+    // Dispatcher
+    template<template <class T1, class T2> class F, class V, class E>
+    BOOST_UBLAS_INLINE
+    void vector_assign (V &v, const vector_expression<E> &e) {
+        typedef typename vector_assign_traits<typename V::storage_category,
+                                              F<typename V::reference, typename E::value_type>::computed,
+                                              typename E::const_iterator::iterator_category>::storage_category storage_category;
+        vector_assign<F> (v, e, storage_category ());
+    }
+
+    template<class SC, class RI>
+    struct vector_swap_traits {
+        typedef SC storage_category;
+    };
+
+    template<>
+    struct vector_swap_traits<dense_proxy_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<>
+    struct vector_swap_traits<packed_proxy_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    // Dense (proxy) case
+    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_swap (V &v, vector_expression<E> &e, dense_proxy_tag) {
+        typedef F<typename V::iterator::reference, typename E::iterator::reference> functor_type;
+        typedef typename V::difference_type difference_type;
+        difference_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
+        typename V::iterator it (v.begin ());
+        typename E::iterator ite (e ().begin ());
+        while (-- size >= 0)
+            functor_type::apply (*it, *ite), ++ it, ++ ite;
+    }
+    // Packed (proxy) case
+    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_swap (V &v, vector_expression<E> &e, packed_proxy_tag) {
+        typedef F<typename V::iterator::reference, typename E::iterator::reference> functor_type;
+        typedef typename V::difference_type difference_type;
+        typename V::iterator it (v.begin ());
+        typename V::iterator it_end (v.end ());
+        typename E::iterator ite (e ().begin ());
+        typename E::iterator ite_end (e ().end ());
+        difference_type it_size (it_end - it);
+        difference_type ite_size (ite_end - ite);
+        if (it_size > 0 && ite_size > 0) {
+            difference_type size ((std::min) (difference_type (it.index () - ite.index ()), ite_size));
+            if (size > 0) {
+                ite += size;
+                ite_size -= size;
+            }
+        }
+        if (it_size > 0 && ite_size > 0) {
+            difference_type size ((std::min) (difference_type (ite.index () - it.index ()), it_size));
+            if (size > 0)
+                it_size -= size;
+        }
+        difference_type size ((std::min) (it_size, ite_size));
+        it_size -= size;
+        ite_size -= size;
+        while (-- size >= 0)
+            functor_type::apply (*it, *ite), ++ it, ++ ite;
+    }
+    // Sparse proxy case
+    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_swap (V &v, vector_expression<E> &e, sparse_proxy_tag) {
+        BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
+        typedef F<typename V::iterator::reference, typename E::iterator::reference> functor_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::difference_type difference_type;
+
+        detail::make_conformant (v, e);
+        // FIXME should be a seperate restriction for E
+        detail::make_conformant (e (), v);
+
+        typename V::iterator it (v.begin ());
+        typename V::iterator it_end (v.end ());
+        typename E::iterator ite (e ().begin ());
+        typename E::iterator ite_end (e ().end ());
+        if (it != it_end && ite != ite_end) {
+            size_type it_index = it.index (), ite_index = ite.index ();
+            while (true) {
+                difference_type compare = it_index - ite_index;
+                if (compare == 0) {
+                    functor_type::apply (*it, *ite);
+                    ++ it, ++ ite;
+                    if (it != it_end && ite != ite_end) {
+                        it_index = it.index ();
+                        ite_index = ite.index ();
+                    } else
+                        break;
+                } else if (compare < 0) {
+                    increment (it, it_end, - compare);
+                    if (it != it_end)
+                        it_index = it.index ();
+                    else
+                        break;
+                } else if (compare > 0) {
+                    increment (ite, ite_end, compare);
+                    if (ite != ite_end)
+                        ite_index = ite.index ();
+                    else
+                        break;
+                }
+            }
+        }
+
+#if BOOST_UBLAS_TYPE_CHECK
+        increment (ite, ite_end);
+        increment (it, it_end);
+#endif
+    }
+
+    // Dispatcher
+    template<template <class T1, class T2> class F, class V, class E>
+    BOOST_UBLAS_INLINE
+    void vector_swap (V &v, vector_expression<E> &e) {
+        typedef typename vector_swap_traits<typename V::storage_category,
+                                            typename E::const_iterator::iterator_category>::storage_category storage_category;
+        vector_swap<F> (v, e, storage_category ());
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/doxydoc.hpp b/include/boost/numeric/ublas/doxydoc.hpp
new file mode 100644
index 0000000..aa22bd8
--- /dev/null
+++ b/include/boost/numeric/ublas/doxydoc.hpp
@@ -0,0 +1,58 @@
+//  Copyright (c) 2010-2011 David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+/** \mainpage BOOST uBLAS: a Linear Algebra Library
+ *
+ * This is the API Reference Documentation. 
+ *
+ * \section main_classes Main classes
+ * 
+ * \subsection listvector Vectors
+ * - \link #boost::numeric::ublas::vector                    vector \endlink
+ * - \link #boost::numeric::ublas::bounded_vector            bounded_vector \endlink
+ * - \link #boost::numeric::ublas::zero_vector                zero_vector \endlink
+ * - \link #boost::numeric::ublas::unit_vector                unit_vector \endlink
+ * - \link #boost::numeric::ublas::scalar_vector            scalar_vector \endlink
+ * - \link #boost::numeric::ublas::c_vector                c_vector \endlink
+ * - \link #boost::numeric::ublas::vector_slice                vector_slice \endlink
+ * - \link #boost::numeric::ublas::vector_range                vector_range \endlink
+ * - \link #boost::numeric::ublas::vector_indirect            vector_indirect \endlink
+ * - \link #boost::numeric::ublas::mapped_vector            mapped_vector \endlink
+ * - \link #boost::numeric::ublas::compressed_vector            compressed_vector \endlink
+ * - \link #boost::numeric::ublas::coordinate_vector            coordinate_vector \endlink
+ * - \link #boost::numeric::ublas::matrix_row                matrix_row \endlink
+ * - \link #boost::numeric::ublas::matrix_column            matrix_column \endlink
+ *
+ * \subsection listmatrix Matrices
+ * - \link #boost::numeric::ublas::matrix                    matrix \endlink
+ * - \link #boost::numeric::ublas::banded_matrix            banded_matrix \endlink
+ * - \link #boost::numeric::ublas::diagonal_matrix            diagonal_matrix \endlink
+ * - \link #boost::numeric::ublas::banded_adaptor            banded_adaptor \endlink
+ * - \link #boost::numeric::ublas::diagonal_adaptor            diagonal_adaptor \endlink
+ * - \link #boost::numeric::ublas::hermitian_matrix            hermitian_matrix \endlink
+ * - \link #boost::numeric::ublas::hermitian_adaptor            hermitian_adaptor \endlink
+ * - \link #boost::numeric::ublas::symmetric_matrix            symmetric_matrix \endlink
+ * - \link #boost::numeric::ublas::symmetric_adaptor            symmetric_adaptor \endlink
+ * - \link #boost::numeric::ublas::triangular_matrix            triangular_matrix \endlink
+ * - \link #boost::numeric::ublas::triangular_adaptor            triangular_adaptor \endlink
+ * - \link #boost::numeric::ublas::vector_of_vector            vector_of_vector \endlink
+ * - \link #boost::numeric::ublas::bounded_matrix            bounded_matrix \endlink
+ * - \link #boost::numeric::ublas::zero_matrix                 zero_matrix  \endlink
+ * - \link #boost::numeric::ublas::identity_matrix            identity_matrix \endlink
+ * - \link #boost::numeric::ublas::scalar_matrix             scalar_matrix  \endlink
+ * - \link #boost::numeric::ublas::c_matrix                c_matrix \endlink
+ * - \link #boost::numeric::ublas::matrix_vector_range        matrix_vector_range \endlink
+ * - \link #boost::numeric::ublas::matrix_vector_slice        matrix_vector_slice \endlink
+ * - \link #boost::numeric::ublas::matrix_vector_indirect        matrix_vector_indirect \endlink
+ * - \link #boost::numeric::ublas::matrix_range                matrix_range \endlink
+ * - \link #boost::numeric::ublas::matrix_slice                matrix_slice \endlink
+ * - \link #boost::numeric::ublas::matrix_indirect            matrix_indirect \endlink
+ * - \link #boost::numeric::ublas::mapped_matrix            mapped_matrix \endlink
+ * - \link #boost::numeric::ublas::mapped_vector_of_mapped_vector    mapped_vector_of_mapped_vector \endlink
+ * - \link #boost::numeric::ublas::compressed_matrix            compressed_matrix \endlink
+ * - \link #boost::numeric::ublas::coordinate_matrix            coordinate_matrix \endlink
+ * - \link #boost::numeric::ublas::generalized_vector_of_vector    generalized_vector_of_vector \endlink
+ */
diff --git a/include/boost/numeric/ublas/exception.hpp b/include/boost/numeric/ublas/exception.hpp
new file mode 100644
index 0000000..5354298
--- /dev/null
+++ b/include/boost/numeric/ublas/exception.hpp
@@ -0,0 +1,297 @@
+//  Copyright (c) 2000-2011 Joerg Walter, Mathias Koch, David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef _BOOST_UBLAS_EXCEPTION_
+#define _BOOST_UBLAS_EXCEPTION_
+
+#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
+#include <stdexcept>
+#else
+#include <cstdlib>
+#endif
+#ifndef BOOST_UBLAS_NO_STD_CERR
+#include <iostream>
+#endif
+
+#include <boost/numeric/ublas/detail/config.hpp>
+
+namespace boost { namespace numeric { namespace ublas {
+
+    /** \brief Exception raised when a division by zero occurs
+     */
+    struct divide_by_zero
+#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
+        // Inherit from standard exceptions as requested during review.
+        : public std::runtime_error 
+    {
+        explicit divide_by_zero (const char *s = "divide by zero") :
+            std::runtime_error (s) {}
+        void raise () {
+            throw *this;
+        }
+#else
+    {
+        divide_by_zero ()
+            {}
+        explicit divide_by_zero (const char *)
+            {}
+        void raise () {
+            std::abort ();
+        }
+#endif
+    };
+
+    /** \brief Expception raised when some interal errors occurs like computations errors, zeros values where you should not have zeros, etc...
+     */
+    struct internal_logic
+#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
+        // Inherit from standard exceptions as requested during review.
+        : public std::logic_error {
+        explicit internal_logic (const char *s = "internal logic") :
+            std::logic_error (s) {}
+        void raise () {
+            throw *this;
+        }
+#else
+    {
+        internal_logic ()
+            {}
+        explicit internal_logic (const char *)
+            {}
+        void raise () {
+            std::abort ();
+        }
+#endif
+    };
+
+    struct external_logic
+#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
+        // Inherit from standard exceptions as requested during review.
+        : public std::logic_error {
+        explicit external_logic (const char *s = "external logic") :
+            std::logic_error (s) {}
+        // virtual const char *what () const throw () {
+        //     return "exception: external logic";
+        // }
+        void raise () {
+            throw *this;
+        }
+#else
+    {
+        external_logic ()
+            {}
+        explicit external_logic (const char *)
+            {}
+        void raise () {
+            std::abort ();
+        }
+#endif
+    };
+
+    struct bad_argument
+#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
+        // Inherit from standard exceptions as requested during review.
+        : public std::invalid_argument {
+        explicit bad_argument (const char *s = "bad argument") :
+            std::invalid_argument (s) {}
+        void raise () {
+            throw *this;
+        }
+#else
+    {
+        bad_argument ()
+            {}
+        explicit bad_argument (const char *)
+            {}
+        void raise () {
+            std::abort ();
+        }
+#endif
+    };
+
+    /**
+     */
+    struct bad_size
+#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
+        // Inherit from standard exceptions as requested during review.
+        : public std::domain_error {
+        explicit bad_size (const char *s = "bad size") :
+            std::domain_error (s) {}
+        void raise () {
+            throw *this;
+        }
+#else
+    {
+        bad_size ()
+            {}
+        explicit bad_size (const char *)
+            {}
+        void raise () {
+            std::abort ();
+        }
+#endif
+    };
+
+    struct bad_index
+#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
+        // Inherit from standard exceptions as requested during review.
+        : public std::out_of_range {
+        explicit bad_index (const char *s = "bad index") :
+            std::out_of_range (s) {}
+        void raise () {
+            throw *this;
+        }
+#else
+    {
+        bad_index ()
+            {}
+        explicit bad_index (const char *)
+            {}
+        void raise () {
+            std::abort ();
+        }
+#endif
+    };
+
+    struct singular
+#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
+        // Inherit from standard exceptions as requested during review.
+        : public std::runtime_error {
+        explicit singular (const char *s = "singular") :
+            std::runtime_error (s) {}
+        void raise () {
+            throw *this;
+        }
+#else
+    {
+        singular ()
+            {}
+        explicit singular (const char *)
+            {}
+        void raise () {
+            std::abort ();
+        }
+#endif
+    };
+
+    struct non_real
+#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
+        // Inherit from standard exceptions as requested during review.
+        : public std::domain_error {
+        explicit non_real (const char *s = "exception: non real") :
+            std::domain_error (s) {}
+        void raise () {
+            throw *this;
+        }
+#else
+     {
+        non_real ()
+            {}
+        explicit non_real (const char *)
+            {}
+        void raise () {
+            std::abort ();
+        }
+#endif
+    };
+
+#if BOOST_UBLAS_CHECK_ENABLE
+// Macros are equivilent to 
+//    template<class E>
+//    BOOST_UBLAS_INLINE
+//    void check (bool expression, const E &e) {
+//        if (! expression)
+//            e.raise ();
+//    }
+//    template<class E>
+//    BOOST_UBLAS_INLINE
+//    void check_ex (bool expression, const char *file, int line, const E &e) {
+//        if (! expression)
+//            e.raise ();
+//    }
+#ifndef BOOST_UBLAS_NO_STD_CERR
+#define BOOST_UBLAS_CHECK_FALSE(e) \
+    std::cerr << "Check failed in file " << __FILE__ << " at line " << __LINE__ << ":" << std::endl; \
+    e.raise ();
+#define BOOST_UBLAS_CHECK(expression, e) \
+    if (! (expression)) { \
+        std::cerr << "Check failed in file " << __FILE__ << " at line " << __LINE__ << ":" << std::endl; \
+        std::cerr << #expression << std::endl; \
+        e.raise (); \
+    }
+#define BOOST_UBLAS_CHECK_EX(expression, file, line, e) \
+    if (! (expression)) { \
+        std::cerr << "Check failed in file " << (file) << " at line " << (line) << ":" << std::endl; \
+        std::cerr << #expression << std::endl; \
+        e.raise (); \
+    }
+#else
+#define BOOST_UBLAS_CHECK_FALSE(e) \
+    e.raise ();
+#define BOOST_UBLAS_CHECK(expression, e) \
+    if (! (expression)) { \
+        e.raise (); \
+    }
+#define BOOST_UBLAS_CHECK_EX(expression, file, line, e) \
+    if (! (expression)) { \
+        e.raise (); \
+    }
+#endif
+#else
+// Macros are equivilent to 
+//    template<class E>
+//    BOOST_UBLAS_INLINE
+//    void check (bool expression, const E &e) {}
+//    template<class E>
+//    BOOST_UBLAS_INLINE
+//    void check_ex (bool expression, const char *file, int line, const E &e) {}
+#define BOOST_UBLAS_CHECK_FALSE(e)
+#define BOOST_UBLAS_CHECK(expression, e)
+#define BOOST_UBLAS_CHECK_EX(expression, file, line, e)
+#endif
+
+
+#ifndef BOOST_UBLAS_USE_FAST_SAME
+// Macro is equivilent to 
+//    template<class T>
+//    BOOST_UBLAS_INLINE
+//    const T &same_impl (const T &size1, const T &size2) {
+//        BOOST_UBLAS_CHECK (size1 == size2, bad_argument ());
+//        return (std::min) (size1, size2);
+//    }
+// #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2))
+     // need two types here because different containers can have
+     // different size_types (especially sparse types)
+    template<class T1, class T2>
+    BOOST_UBLAS_INLINE
+    // Kresimir Fresl and Dan Muller reported problems with COMO.
+    // We better change the signature instead of libcomo ;-)
+    // const T &same_impl_ex (const T &size1, const T &size2, const char *file, int line) {
+    T1 same_impl_ex (const T1 &size1, const T2 &size2, const char *file, int line) {
+        BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ());
+        return (size1 < size2)?(size1):(size2);
+    }
+    template<class T>
+    BOOST_UBLAS_INLINE
+    T same_impl_ex (const T &size1, const T &size2, const char *file, int line) {
+        BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ());
+        return (std::min) (size1, size2);
+    }
+#define BOOST_UBLAS_SAME(size1, size2) same_impl_ex ((size1), (size2), __FILE__, __LINE__)
+#else
+// Macros are equivilent to 
+//    template<class T>
+//    BOOST_UBLAS_INLINE
+//    const T &same_impl (const T &size1, const T &size2) {
+//        return size1;
+//    }
+// #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2))
+#define BOOST_UBLAS_SAME(size1, size2) (size1)
+#endif
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/experimental/sparse_view.hpp b/include/boost/numeric/ublas/experimental/sparse_view.hpp
new file mode 100644
index 0000000..3a16410
--- /dev/null
+++ b/include/boost/numeric/ublas/experimental/sparse_view.hpp
@@ -0,0 +1,317 @@
+//
+//  Copyright (c) 2009
+//  Gunter Winkler
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+
+#ifndef _BOOST_UBLAS_SPARSE_VIEW_
+#define _BOOST_UBLAS_SPARSE_VIEW_
+
+#include <boost/numeric/ublas/matrix_expression.hpp>
+#include <boost/numeric/ublas/detail/matrix_assign.hpp>
+#if BOOST_UBLAS_TYPE_CHECK
+#include <boost/numeric/ublas/matrix.hpp>
+#endif
+
+#include <boost/next_prior.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/numeric/ublas/storage.hpp>
+
+namespace boost { namespace numeric { namespace ublas {
+
+    // view a chunk of memory as ublas array
+
+    template < class T >
+    class c_array_view
+        : public storage_array< c_array_view<T> > {
+    private:
+        typedef c_array_view<T> self_type;
+        typedef T * pointer;
+
+    public:
+        // TODO: think about a const pointer
+        typedef const pointer array_type;
+
+        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;
+
+        typedef const_pointer const_iterator;
+        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+        //
+        // typedefs required by vector concept
+        //
+
+        typedef dense_tag  storage_category;
+        typedef const vector_reference<const self_type>    const_closure_type;
+
+        c_array_view(size_type size, array_type data) :
+            size_(size), data_(data)
+        {}
+
+        ~c_array_view()
+        {}
+
+        //
+        // immutable methods of container concept
+        //
+
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return size_;
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return data_ [i];
+        }
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return data_ + size_;
+        }
+
+        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_;
+        array_type data_;
+    };
+
+
+    /** \brief Present existing arrays as compressed array based
+     *  sparse matrix.
+     *  This class provides CRS / CCS storage layout.
+     *
+     *  see also http://www.netlib.org/utk/papers/templates/node90.html
+     *
+     *       \param L layout type, either row_major or column_major
+     *       \param IB index base, use 0 for C indexing and 1 for
+     *       FORTRAN indexing of the internal index arrays. This
+     *       does not affect the operator()(int,int) where the first
+     *       row/column has always index 0.
+     *       \param IA index array type, e.g., int[]
+     *       \param TA value array type, e.g., double[]
+     */
+    template<class L, std::size_t IB, class IA, class JA, class TA>
+    class compressed_matrix_view:
+        public matrix_expression<compressed_matrix_view<L, IB, IA, JA, TA> > {
+
+    public:
+        typedef typename vector_view_traits<TA>::value_type value_type;
+
+    private:
+        typedef value_type &true_reference;
+        typedef value_type *pointer;
+        typedef const value_type *const_pointer;
+        typedef L layout_type;
+        typedef compressed_matrix_view<L, IB, IA, JA, TA> self_type;
+
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        // ISSUE require type consistency check
+        // is_convertable (IA::size_type, TA::size_type)
+        typedef typename boost::remove_cv<typename vector_view_traits<JA>::value_type>::type index_type;
+        // for compatibility, should be removed some day ...
+        typedef index_type size_type;
+        // size_type for the data arrays.
+        typedef typename vector_view_traits<JA>::size_type array_size_type;
+        typedef typename vector_view_traits<JA>::difference_type difference_type;
+        typedef const value_type & const_reference;
+
+        // do NOT define reference type, because class is read only
+        // typedef value_type & reference;
+
+        typedef IA rowptr_array_type;
+        typedef JA index_array_type;
+        typedef TA value_array_type;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+
+        // FIXME: define a corresponding temporary type
+        // typedef compressed_vector<T, IB, IA, TA> vector_temporary_type;
+
+        // FIXME: define a corresponding temporary type
+        // typedef self_type matrix_temporary_type;
+
+        typedef sparse_tag storage_category;
+        typedef typename L::orientation_category orientation_category;
+
+        //
+        // private types for internal use
+        //
+
+    private:
+        typedef typename vector_view_traits<index_array_type>::const_iterator const_subiterator_type;
+
+        //
+        // Construction and destruction
+        //
+    private:
+        /// private default constructor because data must be filled by caller
+        BOOST_UBLAS_INLINE
+        compressed_matrix_view () { }
+
+    public:
+        BOOST_UBLAS_INLINE
+        compressed_matrix_view (index_type n_rows, index_type n_cols, array_size_type nnz
+                                , const rowptr_array_type & iptr
+                                , const index_array_type & jptr
+                                , const value_array_type & values):
+            matrix_expression<self_type> (),
+            size1_ (n_rows), size2_ (n_cols), 
+            nnz_ (nnz),
+            index1_data_ (iptr), 
+            index2_data_ (jptr), 
+            value_data_ (values) {
+            storage_invariants ();
+        }
+
+        BOOST_UBLAS_INLINE
+        compressed_matrix_view(const compressed_matrix_view& o) :
+            size1_(o.size1_), size2_(o.size2_),
+            nnz_(o.nnz_),
+            index1_data_(o.index1_data_),
+            index2_data_(o.index2_data_),
+            value_data_(o.value_data_)
+        {}
+
+        //
+        // implement immutable iterator types
+        //
+
+        class const_iterator1 {};
+        class const_iterator2 {};
+
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        //
+        // implement all read only methods for the matrix expression concept
+        // 
+
+        //! return the number of rows 
+        index_type size1() const {
+            return size1_;
+        }
+
+        //! return the number of columns
+        index_type size2() const {
+            return size2_;
+        }
+
+        //! return value at position (i,j)
+        value_type operator()(index_type i, index_type j) const {
+            const_pointer p = find_element(i,j);
+            if (!p) {
+                return zero_;
+            } else {
+                return *p;
+            }
+        }
+        
+
+    private:
+        //
+        // private helper functions
+        //
+
+        const_pointer find_element (index_type i, index_type j) const {
+            index_type element1 (layout_type::index_M (i, j));
+            index_type element2 (layout_type::index_m (i, j));
+
+            const array_size_type itv      = zero_based( index1_data_[element1] );
+            const array_size_type itv_next = zero_based( index1_data_[element1+1] );
+
+            const_subiterator_type it_start = boost::next(vector_view_traits<index_array_type>::begin(index2_data_),itv);
+            const_subiterator_type it_end = boost::next(vector_view_traits<index_array_type>::begin(index2_data_),itv_next);
+            const_subiterator_type it = find_index_in_row(it_start, it_end, element2) ;
+            
+            if (it == it_end || *it != k_based (element2))
+                return 0;
+            return &value_data_ [it - vector_view_traits<index_array_type>::begin(index2_data_)];
+        }
+
+        const_subiterator_type find_index_in_row(const_subiterator_type it_start
+                                                 , const_subiterator_type it_end
+                                                 , index_type index) const {
+            return std::lower_bound( it_start
+                                     , it_end
+                                     , k_based (index) );
+        }
+
+
+    private:
+        void storage_invariants () const {
+            BOOST_UBLAS_CHECK (index1_data_ [layout_type::size_M (size1_, size2_)] == k_based (nnz_), external_logic ());
+        }
+        
+        index_type size1_;
+        index_type size2_;
+
+        array_size_type nnz_;
+
+        const rowptr_array_type & index1_data_;
+        const index_array_type & index2_data_;
+        const value_array_type & value_data_;
+
+        static const value_type zero_;
+
+        BOOST_UBLAS_INLINE
+        static index_type zero_based (index_type k_based_index) {
+            return k_based_index - IB;
+        }
+        BOOST_UBLAS_INLINE
+        static index_type k_based (index_type zero_based_index) {
+            return zero_based_index + IB;
+        }
+
+        friend class iterator1;
+        friend class iterator2;
+        friend class const_iterator1;
+        friend class const_iterator2;
+    };
+
+    template<class L, std::size_t IB, class IA, class JA, class TA  >
+    const typename compressed_matrix_view<L,IB,IA,JA,TA>::value_type 
+    compressed_matrix_view<L,IB,IA,JA,TA>::zero_ = value_type/*zero*/();
+
+
+    template<class L, std::size_t IB, class IA, class JA, class TA  >
+    compressed_matrix_view<L,IB,IA,JA,TA>
+    make_compressed_matrix_view(typename vector_view_traits<JA>::value_type n_rows
+                                , typename vector_view_traits<JA>::value_type n_cols
+                                , typename vector_view_traits<JA>::size_type nnz
+                                , const IA & ia
+                                , const JA & ja
+                                , const TA & ta) {
+
+        return compressed_matrix_view<L,IB,IA,JA,TA>(n_rows, n_cols, nnz, ia, ja, ta);
+
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/expression_types.hpp b/include/boost/numeric/ublas/expression_types.hpp
new file mode 100644
index 0000000..eecc71a
--- /dev/null
+++ b/include/boost/numeric/ublas/expression_types.hpp
@@ -0,0 +1,506 @@
+//  Copyright (c) 2000-2013
+//  Joerg Walter, Mathias Koch. David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+#ifndef _BOOST_UBLAS_EXPRESSION_TYPE_
+#define _BOOST_UBLAS_EXPRESSION_TYPE_
+
+#include <boost/numeric/ublas/exception.hpp>
+#include <boost/numeric/ublas/traits.hpp>
+#include <boost/numeric/ublas/functional.hpp>
+
+
+// Expression templates based on ideas of Todd Veldhuizen and Geoffrey Furnish
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+
+    /** \brief Base class for uBLAS statically derived expressions using the the Barton Nackman trick
+     *
+     * This is a NonAssignable class
+     * Directly implement nonassignable - simplifes debugging call trace!
+     * 
+     * \tparam E an expression type
+     */
+    template<class E>
+    class ublas_expression {
+    public:
+        typedef E expression_type;
+        /* E can be an incomplete type - to define the following we would need more template arguments
+        typedef typename E::type_category type_category;
+        typedef typename E::value_type value_type;
+        */
+        
+    protected:
+        ublas_expression () {}
+        ~ublas_expression () {}
+    private:
+        const ublas_expression& operator= (const ublas_expression &);
+    };
+
+
+    /** \brief Base class for Scalar Expression models
+     *
+     * It does not model the Scalar Expression concept but all derived types should.
+     * The class defines a common base type and some common interface for all statically 
+     * derived Scalar Expression classes.
+     *
+     * We implement the casts to the statically derived type.
+     *
+     * \tparam E an expression type
+     */
+    template<class E>
+    class scalar_expression:
+        public ublas_expression<E> {
+    public:
+        typedef E expression_type;
+        typedef scalar_tag type_category;
+
+        BOOST_UBLAS_INLINE
+        const expression_type &operator () () const {
+            return *static_cast<const expression_type *> (this);
+        }
+        BOOST_UBLAS_INLINE
+        expression_type &operator () () {
+            return *static_cast<expression_type *> (this);
+        }
+    };
+
+    template<class T>
+    class scalar_reference:
+        public scalar_expression<scalar_reference<T> > {
+
+        typedef scalar_reference<T> self_type;
+    public:
+        typedef T value_type;
+        typedef const value_type &const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<T>,
+                                          const_reference,
+                                          value_type &>::type reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        explicit scalar_reference (reference t):
+            t_ (t) {}
+
+        // Conversion
+        BOOST_UBLAS_INLINE
+        operator value_type () const {
+            return t_;
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        scalar_reference &operator = (const scalar_reference &s) {
+            t_ = s.t_;
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        scalar_reference &operator = (const scalar_expression<AE> &ae) {
+            t_ = ae;
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const scalar_reference &sr) const {
+            return &t_ == &sr.t_;
+        }
+
+    private:
+        reference t_;
+    };
+
+    template<class T>
+    class scalar_value:
+        public scalar_expression<scalar_value<T> > {
+
+        typedef scalar_value<T> self_type;
+    public:
+        typedef T value_type;
+        typedef const value_type &const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<T>,
+                                          const_reference,
+                                          value_type &>::type reference;
+        typedef const scalar_reference<const self_type> const_closure_type;
+        typedef scalar_reference<self_type> closure_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        scalar_value ():
+            t_ () {}
+        BOOST_UBLAS_INLINE
+        scalar_value (const value_type &t):
+            t_ (t) {}
+
+        BOOST_UBLAS_INLINE
+        operator value_type () const {
+            return t_;
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        scalar_value &operator = (const scalar_value &s) {
+            t_ = s.t_;
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        scalar_value &operator = (const scalar_expression<AE> &ae) {
+            t_ = ae;
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const scalar_value &sv) const {
+            return this == &sv;    // self closing on instances value
+        }
+
+    private:
+        value_type t_;
+    };
+
+
+    /** \brief Base class for Vector Expression models
+     *
+     * it does not model the Vector Expression concept but all derived types should.
+     * The class defines a common base type and some common interface for all
+     * statically derived Vector Expression classes.
+     * We implement the casts to the statically derived type.
+     */
+    template<class E>
+    class vector_expression:
+        public ublas_expression<E> {
+    public:
+        static const unsigned complexity = 0;
+        typedef E expression_type;
+        typedef vector_tag type_category;
+        /* E can be an incomplete type - to define the following we would need more template arguments
+        typedef typename E::size_type size_type;
+        */
+ 
+        BOOST_UBLAS_INLINE
+        const expression_type &operator () () const {
+            return *static_cast<const expression_type *> (this);
+        }
+        BOOST_UBLAS_INLINE
+        expression_type &operator () () {
+            return *static_cast<expression_type *> (this);
+        }
+
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+    private:
+        // projection types
+        typedef vector_range<E> vector_range_type;
+        typedef vector_range<const E> const_vector_range_type;
+        typedef vector_slice<E> vector_slice_type;
+        typedef vector_slice<const E> const_vector_slice_type;
+        // vector_indirect_type will depend on the A template parameter 
+        typedef basic_range<> default_range;    // required to avoid range/slice name confusion
+        typedef basic_slice<> default_slice;
+   public:
+        BOOST_UBLAS_INLINE
+        const_vector_range_type operator () (const default_range &r) const {
+            return const_vector_range_type (operator () (), r);
+        }
+        BOOST_UBLAS_INLINE
+        vector_range_type operator () (const default_range &r) {
+            return vector_range_type (operator () (), r);
+        }
+        BOOST_UBLAS_INLINE
+        const_vector_slice_type operator () (const default_slice &s) const {
+            return const_vector_slice_type (operator () (), s);
+        }
+        BOOST_UBLAS_INLINE
+        vector_slice_type operator () (const default_slice &s) {
+            return vector_slice_type (operator () (), s);
+        }
+        template<class A>
+        BOOST_UBLAS_INLINE
+        const vector_indirect<const E, indirect_array<A> > operator () (const indirect_array<A> &ia) const {
+            return vector_indirect<const E, indirect_array<A> >  (operator () (), ia);
+        }
+        template<class A>
+        BOOST_UBLAS_INLINE
+        vector_indirect<E, indirect_array<A> > operator () (const indirect_array<A> &ia) {
+            return vector_indirect<E, indirect_array<A> > (operator () (), ia);
+        }
+
+        BOOST_UBLAS_INLINE
+        const_vector_range_type project (const default_range &r) const {
+            return const_vector_range_type (operator () (), r);
+        }
+        BOOST_UBLAS_INLINE
+        vector_range_type project (const default_range &r) {
+            return vector_range_type (operator () (), r);
+        }
+        BOOST_UBLAS_INLINE
+        const_vector_slice_type project (const default_slice &s) const {
+            return const_vector_slice_type (operator () (), s);
+        }
+        BOOST_UBLAS_INLINE
+        vector_slice_type project (const default_slice &s) {
+            return vector_slice_type (operator () (), s);
+        }
+        template<class A>
+        BOOST_UBLAS_INLINE
+        const vector_indirect<const E, indirect_array<A> > project (const indirect_array<A> &ia) const {
+            return vector_indirect<const E, indirect_array<A> > (operator () (), ia);
+        }
+        template<class A>
+        BOOST_UBLAS_INLINE
+        vector_indirect<E, indirect_array<A> > project (const indirect_array<A> &ia) {
+            return vector_indirect<E, indirect_array<A> > (operator () (), ia);
+        }
+#endif
+    };
+
+    /** \brief Base class for Vector container models
+     *
+     * it does not model the Vector concept but all derived types should.
+     * The class defines a common base type and some common interface for all
+     * statically derived Vector classes
+     * We implement the casts to the statically derived type.
+     */
+    template<class C>
+    class vector_container:
+        public vector_expression<C> {
+    public:
+        static const unsigned complexity = 0;
+        typedef C container_type;
+        typedef vector_tag type_category;
+ 
+        BOOST_UBLAS_INLINE
+        const container_type &operator () () const {
+            return *static_cast<const container_type *> (this);
+        }
+        BOOST_UBLAS_INLINE
+        container_type &operator () () {
+            return *static_cast<container_type *> (this);
+        }
+
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<C>::operator ();
+#endif
+    };
+
+
+    /** \brief Base class for Matrix Expression models
+     *
+     * it does not model the Matrix Expression concept but all derived types should.
+     * The class defines a common base type and some common interface for all
+     * statically derived Matrix Expression classes
+     * We implement the casts to the statically derived type.
+     */
+    template<class E>
+    class matrix_expression:
+        public ublas_expression<E> {
+    private:
+        typedef matrix_expression<E> self_type;
+    public:
+        static const unsigned complexity = 0;
+        typedef E expression_type;
+        typedef matrix_tag type_category;
+        /* E can be an incomplete type - to define the following we would need more template arguments
+        typedef typename E::size_type size_type;
+        */
+
+        BOOST_UBLAS_INLINE
+        const expression_type &operator () () const {
+            return *static_cast<const expression_type *> (this);
+        }
+        BOOST_UBLAS_INLINE
+        expression_type &operator () () {
+            return *static_cast<expression_type *> (this);
+        }
+
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+    private:
+        // projection types
+        typedef vector_range<E> vector_range_type;
+        typedef const vector_range<const E> const_vector_range_type;
+        typedef vector_slice<E> vector_slice_type;
+        typedef const vector_slice<const E> const_vector_slice_type;
+        typedef matrix_row<E> matrix_row_type;
+        typedef const matrix_row<const E> const_matrix_row_type;
+        typedef matrix_column<E> matrix_column_type;
+        typedef const  matrix_column<const E> const_matrix_column_type;
+        typedef matrix_range<E> matrix_range_type;
+        typedef const matrix_range<const E> const_matrix_range_type;
+        typedef matrix_slice<E> matrix_slice_type;
+        typedef const matrix_slice<const E> const_matrix_slice_type;
+        // matrix_indirect_type will depend on the A template parameter 
+        typedef basic_range<> default_range;    // required to avoid range/slice name confusion
+        typedef basic_slice<> default_slice;
+
+    public:
+        BOOST_UBLAS_INLINE
+        const_matrix_row_type operator [] (std::size_t i) const {
+            return const_matrix_row_type (operator () (), i);
+        }
+        BOOST_UBLAS_INLINE
+        matrix_row_type operator [] (std::size_t i) {
+            return matrix_row_type (operator () (), i);
+        }
+        BOOST_UBLAS_INLINE
+        const_matrix_row_type row (std::size_t i) const {
+            return const_matrix_row_type (operator () (), i);
+        }
+        BOOST_UBLAS_INLINE
+        matrix_row_type row (std::size_t i) {
+            return matrix_row_type (operator () (), i);
+        }
+        BOOST_UBLAS_INLINE
+        const_matrix_column_type column (std::size_t j) const {
+            return const_matrix_column_type (operator () (), j);
+        }
+        BOOST_UBLAS_INLINE
+        matrix_column_type column (std::size_t j) {
+            return matrix_column_type (operator () (), j);
+        }
+
+        BOOST_UBLAS_INLINE
+        const_matrix_range_type operator () (const default_range &r1, const default_range &r2) const {
+            return const_matrix_range_type (operator () (), r1, r2);
+        }
+        BOOST_UBLAS_INLINE
+        matrix_range_type operator () (const default_range &r1, const default_range &r2) {
+            return matrix_range_type (operator () (), r1, r2);
+        }
+        BOOST_UBLAS_INLINE
+        const_matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) const {
+            return const_matrix_slice_type (operator () (), s1, s2);
+        }
+        BOOST_UBLAS_INLINE
+        matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) {
+            return matrix_slice_type (operator () (), s1, s2);
+        }
+        template<class A>
+        BOOST_UBLAS_INLINE
+        const matrix_indirect<const E, indirect_array<A> > operator () (const indirect_array<A> &ia1, const indirect_array<A> &ia2) const {
+            return matrix_indirect<const E, indirect_array<A> > (operator () (), ia1, ia2);
+        }
+        template<class A>
+        BOOST_UBLAS_INLINE
+        matrix_indirect<E, indirect_array<A> > operator () (const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
+            return matrix_indirect<E, indirect_array<A> > (operator () (), ia1, ia2);
+        }
+
+        BOOST_UBLAS_INLINE
+        const_matrix_range_type project (const default_range &r1, const default_range &r2) const {
+            return const_matrix_range_type (operator () (), r1, r2);
+        }
+        BOOST_UBLAS_INLINE
+        matrix_range_type project (const default_range &r1, const default_range &r2) {
+            return matrix_range_type (operator () (), r1, r2);
+        }
+        BOOST_UBLAS_INLINE
+        const_matrix_slice_type project (const default_slice &s1, const default_slice &s2) const {
+            return const_matrix_slice_type (operator () (), s1, s2);
+        }
+        BOOST_UBLAS_INLINE
+        matrix_slice_type project (const default_slice &s1, const default_slice &s2) {
+            return matrix_slice_type (operator () (), s1, s2);
+        }
+        template<class A>
+        BOOST_UBLAS_INLINE
+        const matrix_indirect<const E, indirect_array<A> > project (const indirect_array<A> &ia1, const indirect_array<A> &ia2) const {
+            return matrix_indirect<const E, indirect_array<A> > (operator () (), ia1, ia2);
+        }
+        template<class A>
+        BOOST_UBLAS_INLINE
+        matrix_indirect<E, indirect_array<A> > project (const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
+            return matrix_indirect<E, indirect_array<A> > (operator () (), ia1, ia2);
+        }
+#endif
+    };
+
+#ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+    struct iterator1_tag {};
+    struct iterator2_tag {};
+
+    template<class I>
+    BOOST_UBLAS_INLINE
+    typename I::dual_iterator_type begin (const I &it, iterator1_tag) {
+        return it ().find2 (1, it.index1 (), 0);
+    }
+    template<class I>
+    BOOST_UBLAS_INLINE
+    typename I::dual_iterator_type end (const I &it, iterator1_tag) {
+        return it ().find2 (1, it.index1 (), it ().size2 ());
+    }
+    template<class I>
+    BOOST_UBLAS_INLINE
+    typename I::dual_reverse_iterator_type rbegin (const I &it, iterator1_tag) {
+        return typename I::dual_reverse_iterator_type (end (it, iterator1_tag ()));
+    }
+    template<class I>
+    BOOST_UBLAS_INLINE
+    typename I::dual_reverse_iterator_type rend (const I &it, iterator1_tag) {
+        return typename I::dual_reverse_iterator_type (begin (it, iterator1_tag ()));
+    }
+
+    template<class I>
+    BOOST_UBLAS_INLINE
+    typename I::dual_iterator_type begin (const I &it, iterator2_tag) {
+        return it ().find1 (1, 0, it.index2 ());
+    }
+    template<class I>
+    BOOST_UBLAS_INLINE
+    typename I::dual_iterator_type end (const I &it, iterator2_tag) {
+        return it ().find1 (1, it ().size1 (), it.index2 ());
+    }
+    template<class I>
+    BOOST_UBLAS_INLINE
+    typename I::dual_reverse_iterator_type rbegin (const I &it, iterator2_tag) {
+        return typename I::dual_reverse_iterator_type (end (it, iterator2_tag ()));
+    }
+    template<class I>
+    BOOST_UBLAS_INLINE
+    typename I::dual_reverse_iterator_type rend (const I &it, iterator2_tag) {
+        return typename I::dual_reverse_iterator_type (begin (it, iterator2_tag ()));
+    }
+#endif
+
+    /** \brief Base class for Matrix container models
+     *
+     * it does not model the Matrix concept but all derived types should.
+     * The class defines a common base type and some common interface for all
+     * statically derived Matrix classes
+     * We implement the casts to the statically derived type.
+     */
+    template<class C>
+    class matrix_container:
+        public matrix_expression<C> {
+    public:
+        static const unsigned complexity = 0;
+        typedef C container_type;
+        typedef matrix_tag type_category;
+
+        BOOST_UBLAS_INLINE
+        const container_type &operator () () const {
+            return *static_cast<const container_type *> (this);
+        }
+        BOOST_UBLAS_INLINE
+        container_type &operator () () {
+            return *static_cast<container_type *> (this);
+        }
+
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<C>::operator ();
+#endif
+    };
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/functional.hpp b/include/boost/numeric/ublas/functional.hpp
new file mode 100644
index 0000000..c7c9261
--- /dev/null
+++ b/include/boost/numeric/ublas/functional.hpp
@@ -0,0 +1,2066 @@
+//
+//  Copyright (c) 2000-2009
+//  Joerg Walter, Mathias Koch, Gunter Winkler
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_FUNCTIONAL_
+#define _BOOST_UBLAS_FUNCTIONAL_
+
+#include <functional>
+
+#include <boost/core/ignore_unused.hpp>
+
+#include <boost/numeric/ublas/traits.hpp>
+#ifdef BOOST_UBLAS_USE_DUFF_DEVICE
+#include <boost/numeric/ublas/detail/duff.hpp>
+#endif
+#ifdef BOOST_UBLAS_USE_SIMD
+#include <boost/numeric/ublas/detail/raw.hpp>
+#else
+namespace boost { namespace numeric { namespace ublas { namespace raw {
+}}}}
+#endif
+#ifdef BOOST_UBLAS_HAVE_BINDINGS
+#include <boost/numeric/bindings/traits/std_vector.hpp>
+#include <boost/numeric/bindings/traits/ublas_vector.hpp>
+#include <boost/numeric/bindings/traits/ublas_matrix.hpp>
+#include <boost/numeric/bindings/atlas/cblas.hpp>
+#endif
+
+#include <boost/numeric/ublas/detail/definitions.hpp>
+
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    // Scalar functors
+
+    // Unary
+    template<class T>
+    struct scalar_unary_functor {
+        typedef T value_type;
+        typedef typename type_traits<T>::const_reference argument_type;
+        typedef typename type_traits<T>::value_type result_type;
+    };
+
+    template<class T>
+    struct scalar_identity:
+        public scalar_unary_functor<T> {
+        typedef typename scalar_unary_functor<T>::argument_type argument_type;
+        typedef typename scalar_unary_functor<T>::result_type result_type;
+
+        static BOOST_UBLAS_INLINE
+        result_type apply (argument_type t) {
+            return t;
+        }
+    };
+    template<class T>
+    struct scalar_negate:
+        public scalar_unary_functor<T> {
+        typedef typename scalar_unary_functor<T>::argument_type argument_type;
+        typedef typename scalar_unary_functor<T>::result_type result_type;
+
+        static BOOST_UBLAS_INLINE
+        result_type apply (argument_type t) {
+            return - t;
+        }
+    };
+    template<class T>
+    struct scalar_conj:
+        public scalar_unary_functor<T> {
+        typedef typename scalar_unary_functor<T>::value_type value_type;
+        typedef typename scalar_unary_functor<T>::argument_type argument_type;
+        typedef typename scalar_unary_functor<T>::result_type result_type;
+
+        static BOOST_UBLAS_INLINE
+        result_type apply (argument_type t) {
+            return type_traits<value_type>::conj (t);
+        }
+    };
+
+    // Unary returning real
+    template<class T>
+    struct scalar_real_unary_functor {
+        typedef T value_type;
+        typedef typename type_traits<T>::const_reference argument_type;
+        typedef typename type_traits<T>::real_type result_type;
+    };
+
+    template<class T>
+    struct scalar_real:
+        public scalar_real_unary_functor<T> {
+        typedef typename scalar_real_unary_functor<T>::value_type value_type;
+        typedef typename scalar_real_unary_functor<T>::argument_type argument_type;
+        typedef typename scalar_real_unary_functor<T>::result_type result_type;
+
+        static BOOST_UBLAS_INLINE
+        result_type apply (argument_type t) {
+            return type_traits<value_type>::real (t);
+        }
+    };
+    template<class T>
+    struct scalar_imag:
+        public scalar_real_unary_functor<T> {
+        typedef typename scalar_real_unary_functor<T>::value_type value_type;
+        typedef typename scalar_real_unary_functor<T>::argument_type argument_type;
+        typedef typename scalar_real_unary_functor<T>::result_type result_type;
+
+        static BOOST_UBLAS_INLINE
+        result_type apply (argument_type t) {
+            return type_traits<value_type>::imag (t);
+        }
+    };
+
+    // Binary
+    template<class T1, class T2>
+    struct scalar_binary_functor {
+        typedef typename type_traits<T1>::const_reference argument1_type;
+        typedef typename type_traits<T2>::const_reference argument2_type;
+        typedef typename promote_traits<T1, T2>::promote_type result_type;
+    };
+
+    template<class T1, class T2>
+    struct scalar_plus:
+        public scalar_binary_functor<T1, T2> {
+        typedef typename scalar_binary_functor<T1, T2>::argument1_type argument1_type;
+        typedef typename scalar_binary_functor<T1, T2>::argument2_type argument2_type;
+        typedef typename scalar_binary_functor<T1, T2>::result_type result_type;
+
+        static BOOST_UBLAS_INLINE
+        result_type apply (argument1_type t1, argument2_type t2) {
+            return t1 + t2;
+        }
+    };
+    template<class T1, class T2>
+    struct scalar_minus:
+        public scalar_binary_functor<T1, T2> {
+        typedef typename scalar_binary_functor<T1, T2>::argument1_type argument1_type;
+        typedef typename scalar_binary_functor<T1, T2>::argument2_type argument2_type;
+        typedef typename scalar_binary_functor<T1, T2>::result_type result_type;
+
+        static BOOST_UBLAS_INLINE
+        result_type apply (argument1_type t1, argument2_type t2) {
+            return t1 - t2;
+        }
+    };
+    template<class T1, class T2>
+    struct scalar_multiplies:
+        public scalar_binary_functor<T1, T2> {
+        typedef typename scalar_binary_functor<T1, T2>::argument1_type argument1_type;
+        typedef typename scalar_binary_functor<T1, T2>::argument2_type argument2_type;
+        typedef typename scalar_binary_functor<T1, T2>::result_type result_type;
+
+        static BOOST_UBLAS_INLINE
+        result_type apply (argument1_type t1, argument2_type t2) {
+            return t1 * t2;
+        }
+    };
+    template<class T1, class T2>
+    struct scalar_divides:
+        public scalar_binary_functor<T1, T2> {
+        typedef typename scalar_binary_functor<T1, T2>::argument1_type argument1_type;
+        typedef typename scalar_binary_functor<T1, T2>::argument2_type argument2_type;
+        typedef typename scalar_binary_functor<T1, T2>::result_type result_type;
+
+        static BOOST_UBLAS_INLINE
+        result_type apply (argument1_type t1, argument2_type t2) {
+            return t1 / t2;
+        }
+    };
+
+    template<class T1, class T2>
+    struct scalar_binary_assign_functor {
+        // ISSUE Remove reference to avoid reference to reference problems
+        typedef typename type_traits<typename boost::remove_reference<T1>::type>::reference argument1_type;
+        typedef typename type_traits<T2>::const_reference argument2_type;
+    };
+
+    struct assign_tag {};
+    struct computed_assign_tag {};
+
+    template<class T1, class T2>
+    struct scalar_assign:
+        public scalar_binary_assign_functor<T1, T2> {
+        typedef typename scalar_binary_assign_functor<T1, T2>::argument1_type argument1_type;
+        typedef typename scalar_binary_assign_functor<T1, T2>::argument2_type argument2_type;
+#if BOOST_WORKAROUND( __IBMCPP__, <=600 )
+        static const bool computed ;
+#else
+        static const bool computed = false ;
+#endif
+
+        static BOOST_UBLAS_INLINE
+        void apply (argument1_type t1, argument2_type t2) {
+            t1 = t2;
+        }
+
+        template<class U1, class U2>
+        struct rebind {
+            typedef scalar_assign<U1, U2> other;
+        };
+    };
+
+#if BOOST_WORKAROUND( __IBMCPP__, <=600 )
+    template<class T1, class T2>
+    const bool scalar_assign<T1,T2>::computed = false;
+#endif
+
+    template<class T1, class T2>
+    struct scalar_plus_assign:
+        public scalar_binary_assign_functor<T1, T2> {
+        typedef typename scalar_binary_assign_functor<T1, T2>::argument1_type argument1_type;
+        typedef typename scalar_binary_assign_functor<T1, T2>::argument2_type argument2_type;
+#if BOOST_WORKAROUND( __IBMCPP__, <=600 )
+        static const bool computed ;
+#else
+        static const bool computed = true ;
+#endif
+
+        static BOOST_UBLAS_INLINE
+        void apply (argument1_type t1, argument2_type t2) {
+            t1 += t2;
+        }
+
+        template<class U1, class U2>
+        struct rebind {
+            typedef scalar_plus_assign<U1, U2> other;
+        };
+    };
+
+#if BOOST_WORKAROUND( __IBMCPP__, <=600 )
+    template<class T1, class T2>
+    const bool scalar_plus_assign<T1,T2>::computed = true;
+#endif
+
+    template<class T1, class T2>
+    struct scalar_minus_assign:
+        public scalar_binary_assign_functor<T1, T2> {
+        typedef typename scalar_binary_assign_functor<T1, T2>::argument1_type argument1_type;
+        typedef typename scalar_binary_assign_functor<T1, T2>::argument2_type argument2_type;
+#if BOOST_WORKAROUND( __IBMCPP__, <=600 )
+        static const bool computed ;
+#else
+        static const bool computed = true ;
+#endif
+
+        static BOOST_UBLAS_INLINE
+        void apply (argument1_type t1, argument2_type t2) {
+            t1 -= t2;
+        }
+
+        template<class U1, class U2>
+        struct rebind {
+            typedef scalar_minus_assign<U1, U2> other;
+        };
+    };
+
+#if BOOST_WORKAROUND( __IBMCPP__, <=600 )
+    template<class T1, class T2>
+    const bool scalar_minus_assign<T1,T2>::computed = true;
+#endif
+
+    template<class T1, class T2>
+    struct scalar_multiplies_assign:
+        public scalar_binary_assign_functor<T1, T2> {
+        typedef typename scalar_binary_assign_functor<T1, T2>::argument1_type argument1_type;
+        typedef typename scalar_binary_assign_functor<T1, T2>::argument2_type argument2_type;
+        static const bool computed = true;
+
+        static BOOST_UBLAS_INLINE
+        void apply (argument1_type t1, argument2_type t2) {
+            t1 *= t2;
+        }
+
+        template<class U1, class U2>
+        struct rebind {
+            typedef scalar_multiplies_assign<U1, U2> other;
+        };
+    };
+    template<class T1, class T2>
+    struct scalar_divides_assign:
+        public scalar_binary_assign_functor<T1, T2> {
+        typedef typename scalar_binary_assign_functor<T1, T2>::argument1_type argument1_type;
+        typedef typename scalar_binary_assign_functor<T1, T2>::argument2_type argument2_type;
+        static const bool computed ;
+
+        static BOOST_UBLAS_INLINE
+        void apply (argument1_type t1, argument2_type t2) {
+            t1 /= t2;
+        }
+
+        template<class U1, class U2>
+        struct rebind {
+            typedef scalar_divides_assign<U1, U2> other;
+        };
+    };
+    template<class T1, class T2>
+    const bool scalar_divides_assign<T1,T2>::computed = true;
+
+    template<class T1, class T2>
+    struct scalar_binary_swap_functor {
+        typedef typename type_traits<typename boost::remove_reference<T1>::type>::reference argument1_type;
+        typedef typename type_traits<typename boost::remove_reference<T2>::type>::reference argument2_type;
+    };
+
+    template<class T1, class T2>
+    struct scalar_swap:
+        public scalar_binary_swap_functor<T1, T2> {
+        typedef typename scalar_binary_swap_functor<T1, T2>::argument1_type argument1_type;
+        typedef typename scalar_binary_swap_functor<T1, T2>::argument2_type argument2_type;
+
+        static BOOST_UBLAS_INLINE
+        void apply (argument1_type t1, argument2_type t2) {
+            std::swap (t1, t2);
+        }
+
+        template<class U1, class U2>
+        struct rebind {
+            typedef scalar_swap<U1, U2> other;
+        };
+    };
+
+    // Vector functors
+
+    // Unary returning scalar
+    template<class V>
+    struct vector_scalar_unary_functor {
+        typedef typename V::value_type value_type;
+        typedef typename V::value_type result_type;
+    };
+
+    template<class V>
+    struct vector_sum: 
+        public vector_scalar_unary_functor<V> {
+        typedef typename vector_scalar_unary_functor<V>::value_type value_type;
+        typedef typename vector_scalar_unary_functor<V>::result_type result_type;
+
+        template<class E>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const vector_expression<E> &e) { 
+            result_type t = result_type (0);
+            typedef typename E::size_type vector_size_type;
+            vector_size_type size (e ().size ());
+            for (vector_size_type i = 0; i < size; ++ i)
+                t += e () (i);
+            return t;
+        }
+        // Dense case
+        template<class D, class I>
+        static BOOST_UBLAS_INLINE
+        result_type apply (D size, I it) { 
+            result_type t = result_type (0);
+            while (-- size >= 0)
+                t += *it, ++ it;
+            return t; 
+        }
+        // Sparse case
+        template<class I>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I it, const I &it_end) {
+            result_type t = result_type (0);
+            while (it != it_end) 
+                t += *it, ++ it;
+            return t; 
+        }
+    };
+
+    // Unary returning real scalar 
+    template<class V>
+    struct vector_scalar_real_unary_functor {
+        typedef typename V::value_type value_type;
+        typedef typename type_traits<value_type>::real_type real_type;
+        typedef real_type result_type;
+    };
+
+    template<class V>
+    struct vector_norm_1:
+        public vector_scalar_real_unary_functor<V> {
+        typedef typename vector_scalar_real_unary_functor<V>::value_type value_type;
+        typedef typename vector_scalar_real_unary_functor<V>::real_type real_type;
+        typedef typename vector_scalar_real_unary_functor<V>::result_type result_type;
+
+        template<class E>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const vector_expression<E> &e) {
+            real_type t = real_type ();
+            typedef typename E::size_type vector_size_type;
+            vector_size_type size (e ().size ());
+            for (vector_size_type i = 0; i < size; ++ i) {
+                real_type u (type_traits<value_type>::type_abs (e () (i)));
+                t += u;
+            }
+            return t;
+        }
+        // Dense case
+        template<class D, class I>
+        static BOOST_UBLAS_INLINE
+        result_type apply (D size, I it) {
+            real_type t = real_type ();
+            while (-- size >= 0) {
+                real_type u (type_traits<value_type>::norm_1 (*it));
+                t += u;
+                ++ it;
+            }
+            return t;
+        }
+        // Sparse case
+        template<class I>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I it, const I &it_end) {
+            real_type t = real_type ();
+            while (it != it_end) {
+                real_type u (type_traits<value_type>::norm_1 (*it));
+                t += u;
+                ++ it;
+            }
+            return t;
+        }
+    };
+    template<class V>
+    struct vector_norm_2:
+        public vector_scalar_real_unary_functor<V> {
+        typedef typename vector_scalar_real_unary_functor<V>::value_type value_type;
+        typedef typename vector_scalar_real_unary_functor<V>::real_type real_type;
+        typedef typename vector_scalar_real_unary_functor<V>::result_type result_type;
+
+        template<class E>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const vector_expression<E> &e) {
+#ifndef BOOST_UBLAS_SCALED_NORM
+            real_type t = real_type ();
+            typedef typename E::size_type vector_size_type;
+            vector_size_type size (e ().size ());
+            for (vector_size_type i = 0; i < size; ++ i) {
+                real_type u (type_traits<value_type>::norm_2 (e () (i)));
+                t +=  u * u;
+            }
+            return type_traits<real_type>::type_sqrt (t);
+#else
+            real_type scale = real_type ();
+            real_type sum_squares (1);
+            size_type size (e ().size ());
+            for (size_type i = 0; i < size; ++ i) {
+                real_type u (type_traits<value_type>::norm_2 (e () (i)));
+                if ( real_type () /* zero */ == u ) continue;
+                if (scale < u) {
+                    real_type v (scale / u);
+                    sum_squares = sum_squares * v * v + real_type (1);
+                    scale = u;
+                } else {
+                    real_type v (u / scale);
+                    sum_squares += v * v;
+                }
+            }
+            return scale * type_traits<real_type>::type_sqrt (sum_squares);
+#endif
+        }
+        // Dense case
+        template<class D, class I>
+        static BOOST_UBLAS_INLINE
+        result_type apply (D size, I it) {
+#ifndef BOOST_UBLAS_SCALED_NORM
+            real_type t = real_type ();
+            while (-- size >= 0) {
+                real_type u (type_traits<value_type>::norm_2 (*it));
+                t +=  u * u;
+                ++ it;
+            }
+            return type_traits<real_type>::type_sqrt (t);
+#else
+            real_type scale = real_type ();
+            real_type sum_squares (1);
+            while (-- size >= 0) {
+                real_type u (type_traits<value_type>::norm_2 (*it));
+                if (scale < u) {
+                    real_type v (scale / u);
+                    sum_squares = sum_squares * v * v + real_type (1);
+                    scale = u;
+                } else {
+                    real_type v (u / scale);
+                    sum_squares += v * v;
+                }
+                ++ it;
+            }
+            return scale * type_traits<real_type>::type_sqrt (sum_squares);
+#endif
+        }
+        // Sparse case
+        template<class I>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I it, const I &it_end) {
+#ifndef BOOST_UBLAS_SCALED_NORM
+            real_type t = real_type ();
+            while (it != it_end) {
+                real_type u (type_traits<value_type>::norm_2 (*it));
+                t +=  u * u;
+                ++ it;
+            }
+            return type_traits<real_type>::type_sqrt (t);
+#else
+            real_type scale = real_type ();
+            real_type sum_squares (1);
+            while (it != it_end) {
+                real_type u (type_traits<value_type>::norm_2 (*it));
+                if (scale < u) {
+                    real_type v (scale / u);
+                    sum_squares = sum_squares * v * v + real_type (1);
+                    scale = u;
+                } else {
+                    real_type v (u / scale);
+                    sum_squares += v * v;
+                }
+                ++ it;
+            }
+            return scale * type_traits<real_type>::type_sqrt (sum_squares);
+#endif
+        }
+    };
+    template<class V>
+    struct vector_norm_inf:
+        public vector_scalar_real_unary_functor<V> {
+        typedef typename vector_scalar_real_unary_functor<V>::value_type value_type;
+        typedef typename vector_scalar_real_unary_functor<V>::real_type real_type;
+        typedef typename vector_scalar_real_unary_functor<V>::result_type result_type;
+
+        template<class E>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const vector_expression<E> &e) {
+            real_type t = real_type ();
+            typedef typename E::size_type vector_size_type;
+            vector_size_type size (e ().size ());
+            for (vector_size_type i = 0; i < size; ++ i) {
+                real_type u (type_traits<value_type>::norm_inf (e () (i)));
+                if (u > t)
+                    t = u;
+            }
+            return t;
+        }
+        // Dense case
+        template<class D, class I>
+        static BOOST_UBLAS_INLINE
+        result_type apply (D size, I it) {
+            real_type t = real_type ();
+            while (-- size >= 0) {
+                real_type u (type_traits<value_type>::norm_inf (*it));
+                if (u > t)
+                    t = u;
+                ++ it;
+            }
+            return t;
+        }
+        // Sparse case
+        template<class I>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I it, const I &it_end) { 
+            real_type t = real_type ();
+            while (it != it_end) {
+                real_type u (type_traits<value_type>::norm_inf (*it));
+                if (u > t) 
+                    t = u;
+                ++ it;
+            }
+            return t; 
+        }
+    };
+
+    // Unary returning index
+    template<class V>
+    struct vector_scalar_index_unary_functor {
+        typedef typename V::value_type value_type;
+        typedef typename type_traits<value_type>::real_type real_type;
+        typedef typename V::size_type result_type;
+    };
+
+    template<class V>
+    struct vector_index_norm_inf:
+        public vector_scalar_index_unary_functor<V> {
+        typedef typename vector_scalar_index_unary_functor<V>::value_type value_type;
+        typedef typename vector_scalar_index_unary_functor<V>::real_type real_type;
+        typedef typename vector_scalar_index_unary_functor<V>::result_type result_type;
+
+        template<class E>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const vector_expression<E> &e) {
+            // ISSUE For CBLAS compatibility return 0 index in empty case
+            result_type i_norm_inf (0);
+            real_type t = real_type ();
+            typedef typename E::size_type vector_size_type;
+            vector_size_type size (e ().size ());
+            for (vector_size_type i = 0; i < size; ++ i) {
+                real_type u (type_traits<value_type>::norm_inf (e () (i)));
+                if (u > t) {
+                    i_norm_inf = i;
+                    t = u;
+                }
+            }
+            return i_norm_inf;
+        }
+        // Dense case
+        template<class D, class I>
+        static BOOST_UBLAS_INLINE
+        result_type apply (D size, I it) {
+            // ISSUE For CBLAS compatibility return 0 index in empty case
+            result_type i_norm_inf (0);
+            real_type t = real_type ();
+            while (-- size >= 0) {
+                real_type u (type_traits<value_type>::norm_inf (*it));
+                if (u > t) {
+                    i_norm_inf = it.index ();
+                    t = u;
+                }
+                ++ it;
+            }
+            return i_norm_inf;
+        }
+        // Sparse case
+        template<class I>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I it, const I &it_end) {
+            // ISSUE For CBLAS compatibility return 0 index in empty case
+            result_type i_norm_inf (0);
+            real_type t = real_type ();
+            while (it != it_end) {
+                real_type u (type_traits<value_type>::norm_inf (*it));
+                if (u > t) {
+                    i_norm_inf = it.index ();
+                    t = u;
+                }
+                ++ it;
+            }
+            return i_norm_inf;
+        }
+    };
+
+    // Binary returning scalar
+    template<class V1, class V2, class TV>
+    struct vector_scalar_binary_functor {
+        typedef TV value_type;
+        typedef TV result_type;
+    };
+
+    template<class V1, class V2, class TV>
+    struct vector_inner_prod:
+        public vector_scalar_binary_functor<V1, V2, TV> {
+        typedef typename vector_scalar_binary_functor<V1, V2, TV>::value_type value_type;
+        typedef typename vector_scalar_binary_functor<V1, V2, TV>::result_type result_type;
+
+        template<class C1, class C2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const vector_container<C1> &c1,
+                           const vector_container<C2> &c2) {
+#ifdef BOOST_UBLAS_USE_SIMD
+            using namespace raw;
+            typedef typename C1::size_type vector_size_type;
+            vector_size_type size (BOOST_UBLAS_SAME (c1 ().size (), c2 ().size ()));
+            const typename V1::value_type *data1 = data_const (c1 ());
+            const typename V1::value_type *data2 = data_const (c2 ());
+            vector_size_type s1 = stride (c1 ());
+            vector_size_type s2 = stride (c2 ());
+            result_type t = result_type (0);
+            if (s1 == 1 && s2 == 1) {
+                for (vector_size_type i = 0; i < size; ++ i)
+                    t += data1 [i] * data2 [i];
+            } else if (s2 == 1) {
+                for (vector_size_type i = 0, i1 = 0; i < size; ++ i, i1 += s1)
+                    t += data1 [i1] * data2 [i];
+            } else if (s1 == 1) {
+                for (vector_size_type i = 0, i2 = 0; i < size; ++ i, i2 += s2)
+                    t += data1 [i] * data2 [i2];
+            } else {
+                for (vector_size_type i = 0, i1 = 0, i2 = 0; i < size; ++ i, i1 += s1, i2 += s2)
+                    t += data1 [i1] * data2 [i2];
+            }
+            return t;
+#elif defined(BOOST_UBLAS_HAVE_BINDINGS)
+            return boost::numeric::bindings::atlas::dot (c1 (), c2 ());
+#else
+            return apply (static_cast<const vector_expression<C1> > (c1), static_cast<const vector_expression<C2> > (c2));
+#endif
+        }
+        template<class E1, class E2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const vector_expression<E1> &e1,
+                           const vector_expression<E2> &e2) {
+            typedef typename E1::size_type vector_size_type;
+            vector_size_type size (BOOST_UBLAS_SAME (e1 ().size (), e2 ().size ()));
+            result_type t = result_type (0);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            for (vector_size_type i = 0; i < size; ++ i)
+                t += e1 () (i) * e2 () (i);
+#else
+            vector_size_type i (0);
+            DD (size, 4, r, (t += e1 () (i) * e2 () (i), ++ i));
+#endif
+            return t;
+        }
+        // Dense case
+        template<class D, class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (D size, I1 it1, I2 it2) {
+            result_type t = result_type (0);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            while (-- size >= 0)
+                t += *it1 * *it2, ++ it1, ++ it2;
+#else
+            DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2));
+#endif
+            return t;
+        }
+        // Packed case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) {
+            result_type t = result_type (0);
+            typedef typename I1::difference_type vector_difference_type;
+            vector_difference_type it1_size (it1_end - it1);
+            vector_difference_type it2_size (it2_end - it2);
+            vector_difference_type diff (0);
+            if (it1_size > 0 && it2_size > 0)
+                diff = it2.index () - it1.index ();
+            if (diff != 0) {
+                vector_difference_type size = (std::min) (diff, it1_size);
+                if (size > 0) {
+                    it1 += size;
+                    it1_size -= size;
+                    diff -= size;
+                }
+                size = (std::min) (- diff, it2_size);
+                if (size > 0) {
+                    it2 += size;
+                    it2_size -= size;
+                    diff += size;
+                }
+            }
+            vector_difference_type size ((std::min) (it1_size, it2_size));
+            while (-- size >= 0)
+                t += *it1 * *it2, ++ it1, ++ it2;
+            return t;
+        }
+        // Sparse case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) {
+            result_type t = result_type (0);
+            if (it1 != it1_end && it2 != it2_end) {
+                while (true) {
+                    if (it1.index () == it2.index ()) {
+                        t += *it1 * *it2, ++ it1, ++ it2;
+                        if (it1 == it1_end || it2 == it2_end)
+                            break;
+                    } else if (it1.index () < it2.index ()) {
+                        increment (it1, it1_end, it2.index () - it1.index ());
+                        if (it1 == it1_end)
+                            break;
+                    } else if (it1.index () > it2.index ()) {
+                        increment (it2, it2_end, it1.index () - it2.index ());
+                        if (it2 == it2_end)
+                            break;
+                    }
+                }
+            }
+            return t;
+        }
+    };
+
+    // Matrix functors
+
+    // Binary returning vector
+    template<class M1, class M2, class TV>
+    struct matrix_vector_binary_functor {
+        typedef typename M1::size_type size_type;
+        typedef typename M1::difference_type difference_type;
+        typedef TV value_type;
+        typedef TV result_type;
+    };
+
+    template<class M1, class M2, class TV>
+    struct matrix_vector_prod1:
+        public matrix_vector_binary_functor<M1, M2, TV> {
+        typedef typename matrix_vector_binary_functor<M1, M2, TV>::size_type size_type;
+        typedef typename matrix_vector_binary_functor<M1, M2, TV>::difference_type difference_type;
+        typedef typename matrix_vector_binary_functor<M1, M2, TV>::value_type value_type;
+        typedef typename matrix_vector_binary_functor<M1, M2, TV>::result_type result_type;
+
+        template<class C1, class C2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const matrix_container<C1> &c1,
+                           const vector_container<C2> &c2,
+                           size_type i) {
+#ifdef BOOST_UBLAS_USE_SIMD
+            using namespace raw;
+            size_type size = BOOST_UBLAS_SAME (c1 ().size2 (), c2 ().size ());
+            const typename M1::value_type *data1 = data_const (c1 ()) + i * stride1 (c1 ());
+            const typename M2::value_type *data2 = data_const (c2 ());
+            size_type s1 = stride2 (c1 ());
+            size_type s2 = stride (c2 ());
+            result_type t = result_type (0);
+            if (s1 == 1 && s2 == 1) {
+                for (size_type j = 0; j < size; ++ j)
+                    t += data1 [j] * data2 [j];
+            } else if (s2 == 1) {
+                for (size_type j = 0, j1 = 0; j < size; ++ j, j1 += s1)
+                    t += data1 [j1] * data2 [j];
+            } else if (s1 == 1) {
+                for (size_type j = 0, j2 = 0; j < size; ++ j, j2 += s2)
+                    t += data1 [j] * data2 [j2];
+            } else {
+                for (size_type j = 0, j1 = 0, j2 = 0; j < size; ++ j, j1 += s1, j2 += s2)
+                    t += data1 [j1] * data2 [j2];
+            }
+            return t;
+#elif defined(BOOST_UBLAS_HAVE_BINDINGS)
+            return boost::numeric::bindings::atlas::dot (c1 ().row (i), c2 ());
+#else
+            return apply (static_cast<const matrix_expression<C1> > (c1), static_cast<const vector_expression<C2> > (c2, i));
+#endif
+        }
+        template<class E1, class E2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const matrix_expression<E1> &e1,
+                           const vector_expression<E2> &e2,
+                           size_type i) {
+            size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size ());
+            result_type t = result_type (0);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            for (size_type j = 0; j < size; ++ j)
+                t += e1 () (i, j) * e2 () (j);
+#else
+            size_type j (0);
+            DD (size, 4, r, (t += e1 () (i, j) * e2 () (j), ++ j));
+#endif
+            return t;
+        }
+        // Dense case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (difference_type size, I1 it1, I2 it2) {
+            result_type t = result_type (0);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            while (-- size >= 0)
+                t += *it1 * *it2, ++ it1, ++ it2;
+#else
+            DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2));
+#endif
+            return t;
+        }
+        // Packed case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) {
+            result_type t = result_type (0);
+            difference_type it1_size (it1_end - it1);
+            difference_type it2_size (it2_end - it2);
+            difference_type diff (0);
+            if (it1_size > 0 && it2_size > 0)
+                diff = it2.index () - it1.index2 ();
+            if (diff != 0) {
+                difference_type size = (std::min) (diff, it1_size);
+                if (size > 0) {
+                    it1 += size;
+                    it1_size -= size;
+                    diff -= size;
+                }
+                size = (std::min) (- diff, it2_size);
+                if (size > 0) {
+                    it2 += size;
+                    it2_size -= size;
+                    diff += size;
+                }
+            }
+            difference_type size ((std::min) (it1_size, it2_size));
+            while (-- size >= 0)
+                t += *it1 * *it2, ++ it1, ++ it2;
+            return t;
+        }
+        // Sparse case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end,
+                           sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) {
+            result_type t = result_type (0);
+            if (it1 != it1_end && it2 != it2_end) {
+                size_type it1_index = it1.index2 (), it2_index = it2.index ();
+                while (true) {
+                    difference_type compare = it1_index - it2_index;
+                    if (compare == 0) {
+                        t += *it1 * *it2, ++ it1, ++ it2;
+                        if (it1 != it1_end && it2 != it2_end) {
+                            it1_index = it1.index2 ();
+                            it2_index = it2.index ();
+                        } else
+                            break;
+                    } else if (compare < 0) {
+                        increment (it1, it1_end, - compare);
+                        if (it1 != it1_end)
+                            it1_index = it1.index2 ();
+                        else
+                            break;
+                    } else if (compare > 0) {
+                        increment (it2, it2_end, compare);
+                        if (it2 != it2_end)
+                            it2_index = it2.index ();
+                        else
+                            break;
+                    }
+                }
+            }
+            return t;
+        }
+        // Sparse packed case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */,
+                           sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) {
+            result_type t = result_type (0);
+            while (it1 != it1_end) {
+                t += *it1 * it2 () (it1.index2 ());
+                ++ it1;
+            }
+            return t;
+        }
+        // Packed sparse case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end,
+                           packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) {
+            result_type t = result_type (0);
+            while (it2 != it2_end) {
+                t += it1 () (it1.index1 (), it2.index ()) * *it2;
+                ++ it2;
+            }
+            return t;
+        }
+        // Another dispatcher
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end,
+                           sparse_bidirectional_iterator_tag) {
+            typedef typename I1::iterator_category iterator1_category;
+            typedef typename I2::iterator_category iterator2_category;
+            return apply (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ());
+        }
+    };
+
+    template<class M1, class M2, class TV>
+    struct matrix_vector_prod2:
+        public matrix_vector_binary_functor<M1, M2, TV> {
+        typedef typename matrix_vector_binary_functor<M1, M2, TV>::size_type size_type;
+        typedef typename matrix_vector_binary_functor<M1, M2, TV>::difference_type difference_type;
+        typedef typename matrix_vector_binary_functor<M1, M2, TV>::value_type value_type;
+        typedef typename matrix_vector_binary_functor<M1, M2, TV>::result_type result_type;
+
+        template<class C1, class C2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const vector_container<C1> &c1,
+                           const matrix_container<C2> &c2,
+                           size_type i) {
+#ifdef BOOST_UBLAS_USE_SIMD
+            using namespace raw;
+            size_type size = BOOST_UBLAS_SAME (c1 ().size (), c2 ().size1 ());
+            const typename M1::value_type *data1 = data_const (c1 ());
+            const typename M2::value_type *data2 = data_const (c2 ()) + i * stride2 (c2 ());
+            size_type s1 = stride (c1 ());
+            size_type s2 = stride1 (c2 ());
+            result_type t = result_type (0);
+            if (s1 == 1 && s2 == 1) {
+                for (size_type j = 0; j < size; ++ j)
+                    t += data1 [j] * data2 [j];
+            } else if (s2 == 1) {
+                for (size_type j = 0, j1 = 0; j < size; ++ j, j1 += s1)
+                    t += data1 [j1] * data2 [j];
+            } else if (s1 == 1) {
+                for (size_type j = 0, j2 = 0; j < size; ++ j, j2 += s2)
+                    t += data1 [j] * data2 [j2];
+            } else {
+                for (size_type j = 0, j1 = 0, j2 = 0; j < size; ++ j, j1 += s1, j2 += s2)
+                    t += data1 [j1] * data2 [j2];
+            }
+            return t;
+#elif defined(BOOST_UBLAS_HAVE_BINDINGS)
+            return boost::numeric::bindings::atlas::dot (c1 (), c2 ().column (i));
+#else
+            return apply (static_cast<const vector_expression<C1> > (c1), static_cast<const matrix_expression<C2> > (c2, i));
+#endif
+        }
+        template<class E1, class E2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const vector_expression<E1> &e1,
+                           const matrix_expression<E2> &e2,
+                           size_type i) {
+            size_type size = BOOST_UBLAS_SAME (e1 ().size (), e2 ().size1 ());
+            result_type t = result_type (0);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            for (size_type j = 0; j < size; ++ j)
+                t += e1 () (j) * e2 () (j, i);
+#else
+            size_type j (0);
+            DD (size, 4, r, (t += e1 () (j) * e2 () (j, i), ++ j));
+#endif
+            return t;
+        }
+        // Dense case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (difference_type size, I1 it1, I2 it2) {
+            result_type t = result_type (0);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            while (-- size >= 0)
+                t += *it1 * *it2, ++ it1, ++ it2;
+#else
+            DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2));
+#endif
+            return t;
+        }
+        // Packed case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) {
+            result_type t = result_type (0);
+            difference_type it1_size (it1_end - it1);
+            difference_type it2_size (it2_end - it2);
+            difference_type diff (0);
+            if (it1_size > 0 && it2_size > 0)
+                diff = it2.index1 () - it1.index ();
+            if (diff != 0) {
+                difference_type size = (std::min) (diff, it1_size);
+                if (size > 0) {
+                    it1 += size;
+                    it1_size -= size;
+                    diff -= size;
+                }
+                size = (std::min) (- diff, it2_size);
+                if (size > 0) {
+                    it2 += size;
+                    it2_size -= size;
+                    diff += size;
+                }
+            }
+            difference_type size ((std::min) (it1_size, it2_size));
+            while (-- size >= 0)
+                t += *it1 * *it2, ++ it1, ++ it2;
+            return t;
+        }
+        // Sparse case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end,
+                           sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) {
+            result_type t = result_type (0);
+            if (it1 != it1_end && it2 != it2_end) {
+                size_type it1_index = it1.index (), it2_index = it2.index1 ();
+                while (true) {
+                    difference_type compare = it1_index - it2_index;
+                    if (compare == 0) {
+                        t += *it1 * *it2, ++ it1, ++ it2;
+                        if (it1 != it1_end && it2 != it2_end) {
+                            it1_index = it1.index ();
+                            it2_index = it2.index1 ();
+                        } else
+                            break;
+                    } else if (compare < 0) {
+                        increment (it1, it1_end, - compare);
+                        if (it1 != it1_end)
+                            it1_index = it1.index ();
+                        else
+                            break;
+                    } else if (compare > 0) {
+                        increment (it2, it2_end, compare);
+                        if (it2 != it2_end)
+                            it2_index = it2.index1 ();
+                        else
+                            break;
+                    }
+                }
+            }
+            return t;
+        }
+        // Packed sparse case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end,
+                           packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) {
+            result_type t = result_type (0);
+            while (it2 != it2_end) {
+                t += it1 () (it2.index1 ()) * *it2;
+                ++ it2;
+            }
+            return t;
+        }
+        // Sparse packed case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */,
+                           sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) {
+            result_type t = result_type (0);
+            while (it1 != it1_end) {
+                t += *it1 * it2 () (it1.index (), it2.index2 ());
+                ++ it1;
+            }
+            return t;
+        }
+        // Another dispatcher
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end,
+                           sparse_bidirectional_iterator_tag) {
+            typedef typename I1::iterator_category iterator1_category;
+            typedef typename I2::iterator_category iterator2_category;
+            return apply (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ());
+        }
+    };
+
+    // Binary returning matrix
+    template<class M1, class M2, class TV>
+    struct matrix_matrix_binary_functor {
+        typedef typename M1::size_type size_type;
+        typedef typename M1::difference_type difference_type;
+        typedef TV value_type;
+        typedef TV result_type;
+    };
+
+    template<class M1, class M2, class TV>
+    struct matrix_matrix_prod:
+        public matrix_matrix_binary_functor<M1, M2, TV> {
+        typedef typename matrix_matrix_binary_functor<M1, M2, TV>::size_type size_type;
+        typedef typename matrix_matrix_binary_functor<M1, M2, TV>::difference_type difference_type;
+        typedef typename matrix_matrix_binary_functor<M1, M2, TV>::value_type value_type;
+        typedef typename matrix_matrix_binary_functor<M1, M2, TV>::result_type result_type;
+
+        template<class C1, class C2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const matrix_container<C1> &c1,
+                           const matrix_container<C2> &c2,
+                           size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_SIMD
+            using namespace raw;
+            size_type size = BOOST_UBLAS_SAME (c1 ().size2 (), c2 ().sizc1 ());
+            const typename M1::value_type *data1 = data_const (c1 ()) + i * stride1 (c1 ());
+            const typename M2::value_type *data2 = data_const (c2 ()) + j * stride2 (c2 ());
+            size_type s1 = stride2 (c1 ());
+            size_type s2 = stride1 (c2 ());
+            result_type t = result_type (0);
+            if (s1 == 1 && s2 == 1) {
+                for (size_type k = 0; k < size; ++ k)
+                    t += data1 [k] * data2 [k];
+            } else if (s2 == 1) {
+                for (size_type k = 0, k1 = 0; k < size; ++ k, k1 += s1)
+                    t += data1 [k1] * data2 [k];
+            } else if (s1 == 1) {
+                for (size_type k = 0, k2 = 0; k < size; ++ k, k2 += s2)
+                    t += data1 [k] * data2 [k2];
+            } else {
+                for (size_type k = 0, k1 = 0, k2 = 0; k < size; ++ k, k1 += s1, k2 += s2)
+                    t += data1 [k1] * data2 [k2];
+            }
+            return t;
+#elif defined(BOOST_UBLAS_HAVE_BINDINGS)
+            return boost::numeric::bindings::atlas::dot (c1 ().row (i), c2 ().column (j));
+#else
+            boost::ignore_unused(j);
+            return apply (static_cast<const matrix_expression<C1> > (c1), static_cast<const matrix_expression<C2> > (c2, i));
+#endif
+        }
+        template<class E1, class E2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const matrix_expression<E1> &e1,
+                           const matrix_expression<E2> &e2,
+                           size_type i, size_type j) {
+            size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ());
+            result_type t = result_type (0);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            for (size_type k = 0; k < size; ++ k)
+                t += e1 () (i, k) * e2 () (k, j);
+#else
+            size_type k (0);
+            DD (size, 4, r, (t += e1 () (i, k) * e2 () (k, j), ++ k));
+#endif
+            return t;
+        }
+        // Dense case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (difference_type size, I1 it1, I2 it2) {
+            result_type t = result_type (0);
+#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
+            while (-- size >= 0)
+                t += *it1 * *it2, ++ it1, ++ it2;
+#else
+            DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2));
+#endif
+            return t;
+        }
+        // Packed case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, packed_random_access_iterator_tag) {
+            result_type t = result_type (0);
+            difference_type it1_size (it1_end - it1);
+            difference_type it2_size (it2_end - it2);
+            difference_type diff (0);
+            if (it1_size > 0 && it2_size > 0)
+                diff = it2.index1 () - it1.index2 ();
+            if (diff != 0) {
+                difference_type size = (std::min) (diff, it1_size);
+                if (size > 0) {
+                    it1 += size;
+                    it1_size -= size;
+                    diff -= size;
+                }
+                size = (std::min) (- diff, it2_size);
+                if (size > 0) {
+                    it2 += size;
+                    it2_size -= size;
+                    diff += size;
+                }
+            }
+            difference_type size ((std::min) (it1_size, it2_size));
+            while (-- size >= 0)
+                t += *it1 * *it2, ++ it1, ++ it2;
+            return t;
+        }
+        // Sparse case
+        template<class I1, class I2>
+        static BOOST_UBLAS_INLINE
+        result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) {
+            result_type t = result_type (0);
+            if (it1 != it1_end && it2 != it2_end) {
+                size_type it1_index = it1.index2 (), it2_index = it2.index1 ();
+                while (true) {
+                    difference_type compare = difference_type (it1_index - it2_index);
+                    if (compare == 0) {
+                        t += *it1 * *it2, ++ it1, ++ it2;
+                        if (it1 != it1_end && it2 != it2_end) {
+                            it1_index = it1.index2 ();
+                            it2_index = it2.index1 ();
+                        } else
+                            break;
+                    } else if (compare < 0) {
+                        increment (it1, it1_end, - compare);
+                        if (it1 != it1_end)
+                            it1_index = it1.index2 ();
+                        else
+                            break;
+                    } else if (compare > 0) {
+                        increment (it2, it2_end, compare);
+                        if (it2 != it2_end)
+                            it2_index = it2.index1 ();
+                        else
+                            break;
+                    }
+                }
+            }
+            return t;
+        }
+    };
+
+    // Unary returning scalar norm
+    template<class M>
+    struct matrix_scalar_real_unary_functor {
+        typedef typename M::value_type value_type;
+        typedef typename type_traits<value_type>::real_type real_type;
+        typedef real_type result_type;
+    };
+
+    template<class M>
+    struct matrix_norm_1:
+        public matrix_scalar_real_unary_functor<M> {
+        typedef typename matrix_scalar_real_unary_functor<M>::value_type value_type;
+        typedef typename matrix_scalar_real_unary_functor<M>::real_type real_type;
+        typedef typename matrix_scalar_real_unary_functor<M>::result_type result_type;
+
+        template<class E>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const matrix_expression<E> &e) {
+            real_type t = real_type ();
+            typedef typename E::size_type matrix_size_type;
+            matrix_size_type size2 (e ().size2 ());
+            for (matrix_size_type j = 0; j < size2; ++ j) {
+                real_type u = real_type ();
+                matrix_size_type size1 (e ().size1 ());
+                for (matrix_size_type i = 0; i < size1; ++ i) {
+                    real_type v (type_traits<value_type>::norm_1 (e () (i, j)));
+                    u += v;
+                }
+                if (u > t)
+                    t = u;
+            }
+            return t; 
+        }
+    };
+
+    template<class M>
+    struct matrix_norm_frobenius:
+        public matrix_scalar_real_unary_functor<M> {
+        typedef typename matrix_scalar_real_unary_functor<M>::value_type value_type;
+        typedef typename matrix_scalar_real_unary_functor<M>::real_type real_type;
+        typedef typename matrix_scalar_real_unary_functor<M>::result_type result_type;
+
+        template<class E>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const matrix_expression<E> &e) { 
+            real_type t = real_type ();
+            typedef typename E::size_type matrix_size_type;
+            matrix_size_type size1 (e ().size1 ());
+            for (matrix_size_type i = 0; i < size1; ++ i) {
+                matrix_size_type size2 (e ().size2 ());
+                for (matrix_size_type j = 0; j < size2; ++ j) {
+                    real_type u (type_traits<value_type>::norm_2 (e () (i, j)));
+                    t +=  u * u;
+                }
+            }
+            return type_traits<real_type>::type_sqrt (t); 
+        }
+    };
+
+    template<class M>
+    struct matrix_norm_inf: 
+        public matrix_scalar_real_unary_functor<M> {
+        typedef typename matrix_scalar_real_unary_functor<M>::value_type value_type;
+        typedef typename matrix_scalar_real_unary_functor<M>::real_type real_type;
+        typedef typename matrix_scalar_real_unary_functor<M>::result_type result_type;
+
+        template<class E>
+        static BOOST_UBLAS_INLINE
+        result_type apply (const matrix_expression<E> &e) {
+            real_type t = real_type ();
+            typedef typename E::size_type matrix_size_type;
+            matrix_size_type size1 (e ().size1 ());
+            for (matrix_size_type i = 0; i < size1; ++ i) {
+                real_type u = real_type ();
+                matrix_size_type size2 (e ().size2 ());
+                for (matrix_size_type j = 0; j < size2; ++ j) {
+                    real_type v (type_traits<value_type>::norm_inf (e () (i, j)));
+                    u += v;
+                }
+                if (u > t) 
+                    t = u;  
+            }
+            return t; 
+        }
+    };
+
+    // forward declaration
+    template <class Z, class D> struct basic_column_major;
+
+    // This functor defines storage layout and it's properties
+    // matrix (i,j) -> storage [i * size_i + j]
+    template <class Z, class D>
+    struct basic_row_major {
+        typedef Z size_type;
+        typedef D difference_type;
+        typedef row_major_tag orientation_category;
+        typedef basic_column_major<Z,D> transposed_layout;
+
+        static
+        BOOST_UBLAS_INLINE
+        size_type storage_size (size_type size_i, size_type size_j) {
+            // Guard against size_type overflow
+            BOOST_UBLAS_CHECK (size_j == 0 || size_i <= (std::numeric_limits<size_type>::max) () / size_j, bad_size ());
+            return size_i * size_j;
+        }
+
+        // Indexing conversion to storage element
+        static
+        BOOST_UBLAS_INLINE
+        size_type element (size_type i, size_type size_i, size_type j, size_type size_j) {
+            BOOST_UBLAS_CHECK (i < size_i, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_j, bad_index ());
+            detail::ignore_unused_variable_warning(size_i);
+            // Guard against size_type overflow
+            BOOST_UBLAS_CHECK (i <= ((std::numeric_limits<size_type>::max) () - j) / size_j, bad_index ());
+            return i * size_j + j;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type address (size_type i, size_type size_i, size_type j, size_type size_j) {
+            BOOST_UBLAS_CHECK (i <= size_i, bad_index ());
+            BOOST_UBLAS_CHECK (j <= size_j, bad_index ());
+            // Guard against size_type overflow - address may be size_j past end of storage
+            BOOST_UBLAS_CHECK (size_j == 0 || i <= ((std::numeric_limits<size_type>::max) () - j) / size_j, bad_index ());
+            detail::ignore_unused_variable_warning(size_i);
+            return i * size_j + j;
+        }
+
+        // Storage element to index conversion
+        static
+        BOOST_UBLAS_INLINE
+        difference_type distance_i (difference_type k, size_type /* size_i */, size_type size_j) {
+            return size_j != 0 ? k / size_j : 0;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        difference_type distance_j (difference_type k, size_type /* size_i */, size_type /* size_j */) {
+            return k;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type index_i (difference_type k, size_type /* size_i */, size_type size_j) {
+            return size_j != 0 ? k / size_j : 0;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type index_j (difference_type k, size_type /* size_i */, size_type size_j) {
+            return size_j != 0 ? k % size_j : 0;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool fast_i () {
+            return false;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool fast_j () {
+            return true;
+        }
+
+        // Iterating storage elements
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void increment_i (I &it, size_type /* size_i */, size_type size_j) {
+            it += size_j;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void increment_i (I &it, difference_type n, size_type /* size_i */, size_type size_j) {
+            it += n * size_j;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void decrement_i (I &it, size_type /* size_i */, size_type size_j) {
+            it -= size_j;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void decrement_i (I &it, difference_type n, size_type /* size_i */, size_type size_j) {
+            it -= n * size_j;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void increment_j (I &it, size_type /* size_i */, size_type /* size_j */) {
+            ++ it;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void increment_j (I &it, difference_type n, size_type /* size_i */, size_type /* size_j */) {
+            it += n;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void decrement_j (I &it, size_type /* size_i */, size_type /* size_j */) {
+            -- it;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void decrement_j (I &it, difference_type n, size_type /* size_i */, size_type /* size_j */) {
+            it -= n;
+        }
+
+        // Triangular access
+        static
+        BOOST_UBLAS_INLINE
+        size_type triangular_size (size_type size_i, size_type size_j) {
+            size_type size = (std::max) (size_i, size_j);
+            // Guard against size_type overflow - simplified
+            BOOST_UBLAS_CHECK (size == 0 || size / 2 < (std::numeric_limits<size_type>::max) () / size /* +1/2 */, bad_size ());
+            return ((size + 1) * size) / 2;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type lower_element (size_type i, size_type size_i, size_type j, size_type size_j) {
+            BOOST_UBLAS_CHECK (i < size_i, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_j, bad_index ());
+            BOOST_UBLAS_CHECK (i >= j, bad_index ());
+            detail::ignore_unused_variable_warning(size_i);
+            detail::ignore_unused_variable_warning(size_j);
+            // FIXME size_type overflow
+            // sigma_i (i + 1) = (i + 1) * i / 2
+            // i = 0 1 2 3, sigma = 0 1 3 6
+            return ((i + 1) * i) / 2 + j;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type upper_element (size_type i, size_type size_i, size_type j, size_type size_j) {
+            BOOST_UBLAS_CHECK (i < size_i, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_j, bad_index ());
+            BOOST_UBLAS_CHECK (i <= j, bad_index ());
+            // FIXME size_type overflow
+            // sigma_i (size - i) = size * i - i * (i - 1) / 2
+            // i = 0 1 2 3, sigma = 0 4 7 9
+            return (i * (2 * (std::max) (size_i, size_j) - i + 1)) / 2 + j - i;
+        }
+
+        // Major and minor indices
+        static
+        BOOST_UBLAS_INLINE
+        size_type index_M (size_type index1, size_type /* index2 */) {
+            return index1;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type index_m (size_type /* index1 */, size_type index2) {
+            return index2;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type size_M (size_type size_i, size_type /* size_j */) {
+            return size_i;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type size_m (size_type /* size_i */, size_type size_j) {
+            return size_j;
+        }
+    };
+
+    // This functor defines storage layout and it's properties
+    // matrix (i,j) -> storage [i + j * size_i]
+    template <class Z, class D>
+    struct basic_column_major {
+        typedef Z size_type;
+        typedef D difference_type;
+        typedef column_major_tag orientation_category;
+        typedef basic_row_major<Z,D> transposed_layout;
+
+        static
+        BOOST_UBLAS_INLINE
+        size_type storage_size (size_type size_i, size_type size_j) {
+            // Guard against size_type overflow
+            BOOST_UBLAS_CHECK (size_i == 0 || size_j <= (std::numeric_limits<size_type>::max) () / size_i, bad_size ());
+            return size_i * size_j;
+        }
+
+        // Indexing conversion to storage element
+        static
+        BOOST_UBLAS_INLINE
+        size_type element (size_type i, size_type size_i, size_type j, size_type size_j) {
+            BOOST_UBLAS_CHECK (i < size_i, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_j, bad_index ());
+            detail::ignore_unused_variable_warning(size_j);
+            // Guard against size_type overflow
+            BOOST_UBLAS_CHECK (j <= ((std::numeric_limits<size_type>::max) () - i) / size_i, bad_index ());
+            return i + j * size_i;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type address (size_type i, size_type size_i, size_type j, size_type size_j) {
+            BOOST_UBLAS_CHECK (i <= size_i, bad_index ());
+            BOOST_UBLAS_CHECK (j <= size_j, bad_index ());
+            detail::ignore_unused_variable_warning(size_j);
+            // Guard against size_type overflow - address may be size_i past end of storage
+            BOOST_UBLAS_CHECK (size_i == 0 || j <= ((std::numeric_limits<size_type>::max) () - i) / size_i, bad_index ());
+            return i + j * size_i;
+        }
+
+        // Storage element to index conversion
+        static
+        BOOST_UBLAS_INLINE
+        difference_type distance_i (difference_type k, size_type /* size_i */, size_type /* size_j */) {
+            return k;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        difference_type distance_j (difference_type k, size_type size_i, size_type /* size_j */) {
+            return size_i != 0 ? k / size_i : 0;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type index_i (difference_type k, size_type size_i, size_type /* size_j */) {
+            return size_i != 0 ? k % size_i : 0;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type index_j (difference_type k, size_type size_i, size_type /* size_j */) {
+            return size_i != 0 ? k / size_i : 0;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool fast_i () {
+            return true;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool fast_j () {
+            return false;
+        }
+
+        // Iterating
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void increment_i (I &it, size_type /* size_i */, size_type /* size_j */) {
+            ++ it;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void increment_i (I &it, difference_type n, size_type /* size_i */, size_type /* size_j */) {
+            it += n;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void decrement_i (I &it, size_type /* size_i */, size_type /* size_j */) {
+            -- it;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void decrement_i (I &it, difference_type n, size_type /* size_i */, size_type /* size_j */) {
+            it -= n;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void increment_j (I &it, size_type size_i, size_type /* size_j */) {
+            it += size_i;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void increment_j (I &it, difference_type n, size_type size_i, size_type /* size_j */) {
+            it += n * size_i;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void decrement_j (I &it, size_type size_i, size_type /* size_j */) {
+            it -= size_i;
+        }
+        template<class I>
+        static
+        BOOST_UBLAS_INLINE
+        void decrement_j (I &it, difference_type n, size_type size_i, size_type /* size_j */) {
+            it -= n* size_i;
+        }
+
+        // Triangular access
+        static
+        BOOST_UBLAS_INLINE
+        size_type triangular_size (size_type size_i, size_type size_j) {
+            size_type size = (std::max) (size_i, size_j);
+            // Guard against size_type overflow - simplified
+            BOOST_UBLAS_CHECK (size == 0 || size / 2 < (std::numeric_limits<size_type>::max) () / size /* +1/2 */, bad_size ());
+            return ((size + 1) * size) / 2;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type lower_element (size_type i, size_type size_i, size_type j, size_type size_j) {
+            BOOST_UBLAS_CHECK (i < size_i, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_j, bad_index ());
+            BOOST_UBLAS_CHECK (i >= j, bad_index ());
+            // FIXME size_type overflow
+            // sigma_j (size - j) = size * j - j * (j - 1) / 2
+            // j = 0 1 2 3, sigma = 0 4 7 9
+            return i - j + (j * (2 * (std::max) (size_i, size_j) - j + 1)) / 2;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type upper_element (size_type i, size_type size_i, size_type j, size_type size_j) {
+            BOOST_UBLAS_CHECK (i < size_i, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_j, bad_index ());
+            BOOST_UBLAS_CHECK (i <= j, bad_index ());
+            // FIXME size_type overflow
+            // sigma_j (j + 1) = (j + 1) * j / 2
+            // j = 0 1 2 3, sigma = 0 1 3 6
+            return i + ((j + 1) * j) / 2;
+        }
+
+        // Major and minor indices
+        static
+        BOOST_UBLAS_INLINE
+        size_type index_M (size_type /* index1 */, size_type index2) {
+            return index2;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type index_m (size_type index1, size_type /* index2 */) {
+            return index1;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type size_M (size_type /* size_i */, size_type size_j) {
+            return size_j;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type size_m (size_type size_i, size_type /* size_j */) {
+            return size_i;
+        }
+    };
+
+
+    template <class Z>
+    struct basic_full {
+        typedef Z size_type;
+
+        template<class L>
+        static
+        BOOST_UBLAS_INLINE
+        size_type packed_size (L, size_type size_i, size_type size_j) {
+            return L::storage_size (size_i, size_j);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        bool zero (size_type /* i */, size_type /* j */) {
+            return false;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool one (size_type /* i */, size_type /* j */) {
+            return false;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool other (size_type /* i */, size_type /* j */) {
+            return true;
+        }
+        // FIXME: this should not be used at all
+        static
+        BOOST_UBLAS_INLINE
+        size_type restrict1 (size_type i, size_type /* j */) {
+            return i;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type restrict2 (size_type /* i */, size_type j) {
+            return j;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type mutable_restrict1 (size_type i, size_type /* j */) {
+            return i;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type mutable_restrict2 (size_type /* i */, size_type j) {
+            return j;
+        }
+    };
+
+    namespace detail {
+        template < class L >
+        struct transposed_structure {
+            typedef typename L::size_type size_type;
+
+            template<class LAYOUT>
+            static
+            BOOST_UBLAS_INLINE
+            size_type packed_size (LAYOUT l, size_type size_i, size_type size_j) {
+                return L::packed_size(l, size_j, size_i);
+            }
+
+            static
+            BOOST_UBLAS_INLINE
+            bool zero (size_type i, size_type j) {
+                return L::zero(j, i);
+            }
+            static
+            BOOST_UBLAS_INLINE
+            bool one (size_type i, size_type j) {
+                return L::one(j, i);
+            }
+            static
+            BOOST_UBLAS_INLINE
+            bool other (size_type i, size_type j) {
+                return L::other(j, i);
+            }
+            template<class LAYOUT>
+            static
+            BOOST_UBLAS_INLINE
+            size_type element (LAYOUT /* l */, size_type i, size_type size_i, size_type j, size_type size_j) {
+                return L::element(typename LAYOUT::transposed_layout(), j, size_j, i, size_i);
+            }
+
+            static
+            BOOST_UBLAS_INLINE
+            size_type restrict1 (size_type i, size_type j, size_type size1, size_type size2) {
+                return L::restrict2(j, i, size2, size1);
+            }
+            static
+            BOOST_UBLAS_INLINE
+            size_type restrict2 (size_type i, size_type j, size_type size1, size_type size2) {
+                return L::restrict1(j, i, size2, size1);
+            }
+            static
+            BOOST_UBLAS_INLINE
+            size_type mutable_restrict1 (size_type i, size_type j, size_type size1, size_type size2) {
+                return L::mutable_restrict2(j, i, size2, size1);
+            }
+            static
+            BOOST_UBLAS_INLINE
+            size_type mutable_restrict2 (size_type i, size_type j, size_type size1, size_type size2) {
+                return L::mutable_restrict1(j, i, size2, size1);
+            }
+
+            static
+            BOOST_UBLAS_INLINE
+            size_type global_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) {
+                return L::global_restrict2(index2, size2, index1, size1);
+            }
+            static
+            BOOST_UBLAS_INLINE
+            size_type global_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) {
+                return L::global_restrict1(index2, size2, index1, size1);
+            }
+            static
+            BOOST_UBLAS_INLINE
+            size_type global_mutable_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) {
+                return L::global_mutable_restrict2(index2, size2, index1, size1);
+            }
+            static
+            BOOST_UBLAS_INLINE
+            size_type global_mutable_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) {
+                return L::global_mutable_restrict1(index2, size2, index1, size1);
+            }
+        };
+    }
+
+    template <class Z>
+    struct basic_lower {
+        typedef Z size_type;
+        typedef lower_tag triangular_type;
+
+        template<class L>
+        static
+        BOOST_UBLAS_INLINE
+        size_type packed_size (L, size_type size_i, size_type size_j) {
+            return L::triangular_size (size_i, size_j);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        bool zero (size_type i, size_type j) {
+            return j > i;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool one (size_type /* i */, size_type /* j */) {
+            return false;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool other (size_type i, size_type j) {
+            return j <= i;
+        }
+        template<class L>
+        static
+        BOOST_UBLAS_INLINE
+        size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) {
+            return L::lower_element (i, size_i, j, size_j);
+        }
+
+        // return nearest valid index in column j
+        static
+        BOOST_UBLAS_INLINE
+        size_type restrict1 (size_type i, size_type j, size_type size1, size_type /* size2 */) {
+            return (std::max)(j, (std::min) (size1, i));
+        }
+        // return nearest valid index in row i
+        static
+        BOOST_UBLAS_INLINE
+        size_type restrict2 (size_type i, size_type j, size_type /* size1 */, size_type /* size2 */) {
+            return (std::max)(size_type(0), (std::min) (i+1, j));
+        }
+        // return nearest valid mutable index in column j
+        static
+        BOOST_UBLAS_INLINE
+        size_type mutable_restrict1 (size_type i, size_type j, size_type size1, size_type /* size2 */) {
+            return (std::max)(j, (std::min) (size1, i));
+        }
+        // return nearest valid mutable index in row i
+        static
+        BOOST_UBLAS_INLINE
+        size_type mutable_restrict2 (size_type i, size_type j, size_type /* size1 */, size_type /* size2 */) {
+            return (std::max)(size_type(0), (std::min) (i+1, j));
+        }
+
+        // return an index between the first and (1+last) filled row
+        static
+        BOOST_UBLAS_INLINE
+        size_type global_restrict1 (size_type index1, size_type size1, size_type /* index2 */, size_type /* size2 */) {
+            return (std::max)(size_type(0), (std::min)(size1, index1) );
+        }
+        // return an index between the first and (1+last) filled column
+        static
+        BOOST_UBLAS_INLINE
+        size_type global_restrict2 (size_type /* index1 */, size_type /* size1 */, size_type index2, size_type size2) {
+            return (std::max)(size_type(0), (std::min)(size2, index2) );
+        }
+
+        // return an index between the first and (1+last) filled mutable row
+        static
+        BOOST_UBLAS_INLINE
+        size_type global_mutable_restrict1 (size_type index1, size_type size1, size_type /* index2 */, size_type /* size2 */) {
+            return (std::max)(size_type(0), (std::min)(size1, index1) );
+        }
+        // return an index between the first and (1+last) filled mutable column
+        static
+        BOOST_UBLAS_INLINE
+        size_type global_mutable_restrict2 (size_type /* index1 */, size_type /* size1 */, size_type index2, size_type size2) {
+            return (std::max)(size_type(0), (std::min)(size2, index2) );
+        }
+    };
+
+    // the first row only contains a single 1. Thus it is not stored.
+    template <class Z>
+    struct basic_unit_lower : public basic_lower<Z> {
+        typedef Z size_type;
+        typedef unit_lower_tag triangular_type;
+
+        template<class L>
+        static
+        BOOST_UBLAS_INLINE
+        size_type packed_size (L, size_type size_i, size_type size_j) {
+            // Zero size strict triangles are bad at this point
+            BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0, bad_index ());
+            return L::triangular_size (size_i - 1, size_j - 1);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        bool one (size_type i, size_type j) {
+            return j == i;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool other (size_type i, size_type j) {
+            return j < i;
+        }
+        template<class L>
+        static
+        BOOST_UBLAS_INLINE
+        size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) {
+            // Zero size strict triangles are bad at this point
+            BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0 && i != 0, bad_index ());
+            return L::lower_element (i-1, size_i - 1, j, size_j - 1);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        size_type mutable_restrict1 (size_type i, size_type j, size_type size1, size_type /* size2 */) {
+            return (std::max)(j+1, (std::min) (size1, i));
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type mutable_restrict2 (size_type i, size_type j, size_type /* size1 */, size_type /* size2 */) {
+            return (std::max)(size_type(0), (std::min) (i, j));
+        }
+
+        // return an index between the first and (1+last) filled mutable row
+        static
+        BOOST_UBLAS_INLINE
+        size_type global_mutable_restrict1 (size_type index1, size_type size1, size_type /* index2 */, size_type /* size2 */) {
+            return (std::max)(size_type(1), (std::min)(size1, index1) );
+        }
+        // return an index between the first and (1+last) filled mutable column
+        static
+        BOOST_UBLAS_INLINE
+        size_type global_mutable_restrict2 (size_type /* index1 */, size_type /* size1 */, size_type index2, size_type size2) {
+            BOOST_UBLAS_CHECK( size2 >= 1 , external_logic() );
+            return (std::max)(size_type(0), (std::min)(size2-1, index2) );
+        }
+    };
+
+    // the first row only contains no element. Thus it is not stored.
+    template <class Z>
+    struct basic_strict_lower : public basic_unit_lower<Z> {
+        typedef Z size_type;
+        typedef strict_lower_tag triangular_type;
+
+        template<class L>
+        static
+        BOOST_UBLAS_INLINE
+        size_type packed_size (L, size_type size_i, size_type size_j) {
+            // Zero size strict triangles are bad at this point
+            BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0, bad_index ());
+            return L::triangular_size (size_i - 1, size_j - 1);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        bool zero (size_type i, size_type j) {
+            return j >= i;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool one (size_type /*i*/, size_type /*j*/) {
+            return false;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        bool other (size_type i, size_type j) {
+            return j < i;
+        }
+        template<class L>
+        static
+        BOOST_UBLAS_INLINE
+        size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) {
+            // Zero size strict triangles are bad at this point
+            BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0 && i != 0, bad_index ());
+            return L::lower_element (i-1, size_i - 1, j, size_j - 1);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        size_type restrict1 (size_type i, size_type j, size_type size1, size_type size2) {
+            return basic_unit_lower<Z>::mutable_restrict1(i, j, size1, size2);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        size_type restrict2 (size_type i, size_type j, size_type size1, size_type size2) {
+            return basic_unit_lower<Z>::mutable_restrict2(i, j, size1, size2);
+        }
+
+        // return an index between the first and (1+last) filled row
+        static
+        BOOST_UBLAS_INLINE
+        size_type global_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) {
+            return basic_unit_lower<Z>::global_mutable_restrict1(index1, size1, index2, size2);
+        }
+        // return an index between the first and (1+last) filled column
+        static
+        BOOST_UBLAS_INLINE
+        size_type global_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) {
+            return basic_unit_lower<Z>::global_mutable_restrict2(index1, size1, index2, size2);
+        }
+    };
+
+
+    template <class Z>
+    struct basic_upper : public detail::transposed_structure<basic_lower<Z> >
+    { 
+        typedef upper_tag triangular_type;
+    };
+
+    template <class Z>
+    struct basic_unit_upper : public detail::transposed_structure<basic_unit_lower<Z> >
+    { 
+        typedef unit_upper_tag triangular_type;
+    };
+
+    template <class Z>
+    struct basic_strict_upper : public detail::transposed_structure<basic_strict_lower<Z> >
+    { 
+        typedef strict_upper_tag triangular_type;
+    };
+
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/fwd.hpp b/include/boost/numeric/ublas/fwd.hpp
new file mode 100644
index 0000000..69b3dd2
--- /dev/null
+++ b/include/boost/numeric/ublas/fwd.hpp
@@ -0,0 +1,229 @@
+//
+//  Copyright (c) 2000-2010
+//  Joerg Walter, Mathias Koch, David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+/// \file fwd.hpp is essentially used to forward declare the main types
+
+#ifndef BOOST_UBLAS_FWD_H
+#define BOOST_UBLAS_FWD_H
+
+#include <memory>
+
+#ifdef BOOST_UBLAS_CPP_GE_2011
+#include <array>
+#endif
+
+namespace boost { namespace numeric { namespace ublas {
+
+    // Storage types
+    template<class T, class ALLOC = std::allocator<T> >
+    class unbounded_array;
+
+    template<class T, std::size_t N, class ALLOC = std::allocator<T> >
+    class bounded_array;
+
+    template <class Z = std::size_t, class D = std::ptrdiff_t>
+    class basic_range;
+    template <class Z = std::size_t, class D = std::ptrdiff_t>
+    class basic_slice;
+    typedef basic_range<> range;
+    typedef basic_slice<> slice;
+    template<class A = unbounded_array<std::size_t> >
+    class indirect_array;
+
+    template<class I, class T, class ALLOC = std::allocator<std::pair<const I, T> > >
+    class map_std;
+    template<class I, class T, class ALLOC = std::allocator<std::pair<I, T> > >
+    class map_array;
+
+    // Expression types
+    struct scalar_tag {};
+    
+    struct vector_tag {};
+    template<class E>
+    class vector_expression;
+    template<class C>
+    class vector_container;
+
+    template<class E>
+    class vector_reference;
+
+    struct matrix_tag {};
+
+    template<class E>
+    class matrix_expression;
+    template<class C>
+    class matrix_container;
+
+    template<class E>
+    class matrix_reference;
+
+    template<class V>
+    class vector_range;
+    template<class V>
+    class vector_slice;
+    template<class V, class IA = indirect_array<> >
+    class vector_indirect;
+
+    template<class M>
+    class matrix_row;
+    template<class M>
+    class matrix_column;
+    template<class M>
+    class matrix_vector_range;
+    template<class M>
+    class matrix_vector_slice;
+    template<class M, class IA = indirect_array<> >
+    class matrix_vector_indirect;
+    template<class M>
+    class matrix_range;
+    template<class M>
+    class matrix_slice;
+    template<class M, class IA = indirect_array<> >
+    class matrix_indirect;
+
+    template<class T, class A = unbounded_array<T> >
+    class vector;
+#ifdef BOOST_UBLAS_CPP_GE_2011
+    template<class T, std::size_t N, class A = std::array<T, N> >
+    class fixed_vector;
+#endif
+    template<class T, std::size_t N>
+    class bounded_vector;
+
+    template<class T = int, class ALLOC = std::allocator<T> >
+    class unit_vector;
+    template<class T = int, class ALLOC = std::allocator<T> >
+    class zero_vector;
+    template<class T = int, class ALLOC = std::allocator<T> >
+    class scalar_vector;
+
+    template<class T, std::size_t N>
+    class c_vector;
+
+    // Sparse vectors
+    template<class T, class A = map_std<std::size_t, T> >
+    class mapped_vector;
+    template<class T, std::size_t IB = 0, class IA = unbounded_array<std::size_t>, class TA = unbounded_array<T> >
+    class compressed_vector;
+    template<class T, std::size_t IB = 0, class IA = unbounded_array<std::size_t>, class TA = unbounded_array<T> >
+    class coordinate_vector;
+
+    // Matrix orientation type
+    struct unknown_orientation_tag {};
+    struct row_major_tag {};
+    struct column_major_tag {};
+
+    // Matrix storage layout parameterisation
+    template <class Z = std::size_t, class D = std::ptrdiff_t>
+    struct basic_row_major;
+    typedef basic_row_major<> row_major;
+
+    template <class Z = std::size_t, class D = std::ptrdiff_t>
+    struct basic_column_major;
+    typedef basic_column_major<> column_major;
+
+    template<class T, class L = row_major, class A = unbounded_array<T> >
+    class matrix;
+#ifdef BOOST_UBLAS_CPP_GE_2011
+    template<class T, std::size_t M, std::size_t N, class L = row_major, class A = std::array<T, M*N> >
+    class fixed_matrix;
+#endif
+    template<class T, std::size_t M, std::size_t N, class L = row_major>
+    class bounded_matrix;
+
+    template<class T = int, class ALLOC = std::allocator<T> >
+    class identity_matrix;
+    template<class T = int, class ALLOC = std::allocator<T> >
+    class zero_matrix;
+    template<class T = int, class ALLOC = std::allocator<T> >
+    class scalar_matrix;
+
+    template<class T, std::size_t M, std::size_t N>
+    class c_matrix;
+
+    template<class T, class L = row_major, class A = unbounded_array<unbounded_array<T> > >
+    class vector_of_vector;
+
+    template<class T, class L = row_major, class A = vector<compressed_vector<T> > >
+    class generalized_vector_of_vector;
+
+    // Triangular matrix type
+    struct lower_tag {};
+    struct upper_tag {};
+    struct unit_lower_tag : public lower_tag {};
+    struct unit_upper_tag : public upper_tag {};
+    struct strict_lower_tag : public lower_tag {};
+    struct strict_upper_tag : public upper_tag {};
+
+    // Triangular matrix parameterisation
+    template <class Z = std::size_t>
+    struct basic_full;
+    typedef basic_full<> full;
+
+    template <class Z = std::size_t>
+    struct basic_lower;
+    typedef basic_lower<> lower;
+
+    template <class Z = std::size_t>
+    struct basic_upper;
+    typedef basic_upper<> upper;
+
+    template <class Z = std::size_t>
+    struct basic_unit_lower;
+    typedef basic_unit_lower<> unit_lower;
+
+    template <class Z = std::size_t>
+    struct basic_unit_upper;
+    typedef basic_unit_upper<> unit_upper;
+
+    template <class Z = std::size_t>
+    struct basic_strict_lower;
+    typedef basic_strict_lower<> strict_lower;
+
+    template <class Z = std::size_t>
+    struct basic_strict_upper;
+    typedef basic_strict_upper<> strict_upper;
+
+    // Special matrices
+    template<class T, class L = row_major, class A = unbounded_array<T> >
+    class banded_matrix;
+    template<class T, class L = row_major, class A = unbounded_array<T> >
+    class diagonal_matrix;
+
+    template<class T, class TRI = lower, class L = row_major, class A = unbounded_array<T> >
+    class triangular_matrix;
+    template<class M, class TRI = lower>
+    class triangular_adaptor;
+
+    template<class T, class TRI = lower, class L = row_major, class A = unbounded_array<T> >
+    class symmetric_matrix;
+    template<class M, class TRI = lower>
+    class symmetric_adaptor;
+
+    template<class T, class TRI = lower, class L = row_major, class A = unbounded_array<T> >
+    class hermitian_matrix;
+    template<class M, class TRI = lower>
+    class hermitian_adaptor;
+
+    // Sparse matrices
+    template<class T, class L = row_major, class A = map_std<std::size_t, T> >
+    class mapped_matrix;
+    template<class T, class L = row_major, class A = map_std<std::size_t, map_std<std::size_t, T> > >
+    class mapped_vector_of_mapped_vector;
+    template<class T, class L = row_major, std::size_t IB = 0, class IA = unbounded_array<std::size_t>, class TA = unbounded_array<T> >
+    class compressed_matrix;
+    template<class T, class L = row_major, std::size_t IB = 0, class IA = unbounded_array<std::size_t>, class TA = unbounded_array<T> >
+    class coordinate_matrix;
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/hermitian.hpp b/include/boost/numeric/ublas/hermitian.hpp
new file mode 100644
index 0000000..f219b70
--- /dev/null
+++ b/include/boost/numeric/ublas/hermitian.hpp
@@ -0,0 +1,2633 @@
+//
+//  Copyright (c) 2000-2010
+//  Joerg Walter, Mathias Koch, David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef BOOST_UBLAS_HERMITIAN_H
+#define BOOST_UBLAS_HERMITIAN_H
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/triangular.hpp>  // for resize_preserve
+#include <boost/numeric/ublas/detail/temporary.hpp>
+
+// Iterators based on ideas of Jeremy Siek
+// Hermitian matrices are square. Thanks to Peter Schmitteckert for spotting this.
+
+namespace boost { namespace numeric { namespace ublas {
+
+    template<class M>
+    bool is_hermitian (const M &m) {
+        typedef typename M::size_type size_type;
+
+        if (m.size1 () != m.size2 ())
+            return false;
+        size_type size = BOOST_UBLAS_SAME (m.size1 (), m.size2 ());
+        for (size_type i = 0; i < size; ++ i) {
+            for (size_type j = i; j < size; ++ j) {
+                if (m (i, j) != conj (m (j, i)))
+                    return false;
+            }
+        }
+        return true;
+    }
+
+#ifdef BOOST_UBLAS_STRICT_HERMITIAN
+
+    template<class M>
+    class hermitian_matrix_element:
+       public container_reference<M> {
+    public:
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef value_type *pointer;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        hermitian_matrix_element (matrix_type &m, size_type i, size_type j, value_type d):
+            container_reference<matrix_type> (m), i_ (i), j_ (j), d_ (d), dirty_ (false) {}
+        BOOST_UBLAS_INLINE
+        ~hermitian_matrix_element () {
+            if (dirty_)
+                (*this) ().insert_element (i_, j_, d_);
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        hermitian_matrix_element &operator = (const hermitian_matrix_element &p) {
+            // Overide the implict copy assignment
+            d_ = p.d_;
+            dirty_ = true;
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix_element &operator = (const D &d) {
+            d_ = d;
+            dirty_ = true;
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix_element &operator += (const D &d) {
+            d_ += d;
+            dirty_ = true;
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix_element &operator -= (const D &d) {
+            d_ -= d;
+            dirty_ = true;
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix_element &operator *= (const D &d) {
+            d_ *= d;
+            dirty_ = true;
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix_element &operator /= (const D &d) {
+            d_ /= d;
+            dirty_ = true;
+            return *this;
+        }
+        
+        // Comparison
+        template<class D>
+        BOOST_UBLAS_INLINE
+        bool operator == (const D &d) const {
+            return d_ == d;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        bool operator != (const D &d) const {
+            return d_ != d;
+        }
+
+        // Conversion
+        BOOST_UBLAS_INLINE
+        operator const_reference () const {
+            return d_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (hermitian_matrix_element p) {
+            if (this != &p) {
+                dirty_ = true;
+                p.dirty_ = true;
+                std::swap (d_, p.d_);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (hermitian_matrix_element p1, hermitian_matrix_element p2) {
+            p1.swap (p2);
+        }
+
+    private:
+        size_type i_;
+        size_type j_;
+        value_type d_;
+        bool dirty_;
+    };
+
+    template<class M>
+    struct type_traits<hermitian_matrix_element<M> > {
+        typedef typename M::value_type element_type;
+        typedef type_traits<hermitian_matrix_element<M> > self_type;
+        typedef typename type_traits<element_type>::value_type value_type;
+        typedef typename type_traits<element_type>::const_reference const_reference;
+        typedef hermitian_matrix_element<M> reference;
+        typedef typename type_traits<element_type>::real_type real_type;
+        typedef typename type_traits<element_type>::precision_type precision_type;
+
+        static const unsigned plus_complexity = type_traits<element_type>::plus_complexity;
+        static const unsigned multiplies_complexity = type_traits<element_type>::multiplies_complexity;
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type real (const_reference t) {
+            return type_traits<element_type>::real (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type imag (const_reference t) {
+            return type_traits<element_type>::imag (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        value_type conj (const_reference t) {
+            return type_traits<element_type>::conj (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type type_abs (const_reference t) {
+            return type_traits<element_type>::type_abs (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        value_type type_sqrt (const_reference t) {
+            return type_traits<element_type>::type_sqrt (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_1 (const_reference t) {
+            return type_traits<element_type>::norm_1 (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_2 (const_reference t) {
+            return type_traits<element_type>::norm_2 (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_inf (const_reference t) {
+            return type_traits<element_type>::norm_inf (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        bool equals (const_reference t1, const_reference t2) {
+            return type_traits<element_type>::equals (t1, t2);
+        }
+    };
+
+    template<class M1, class T2>
+    struct promote_traits<hermitian_matrix_element<M1>, T2> {
+        typedef typename promote_traits<typename hermitian_matrix_element<M1>::value_type, T2>::promote_type promote_type;
+    };
+    template<class T1, class M2>
+    struct promote_traits<T1, hermitian_matrix_element<M2> > {
+        typedef typename promote_traits<T1, typename hermitian_matrix_element<M2>::value_type>::promote_type promote_type;
+    };
+    template<class M1, class M2>
+    struct promote_traits<hermitian_matrix_element<M1>, hermitian_matrix_element<M2> > {
+        typedef typename promote_traits<typename hermitian_matrix_element<M1>::value_type,
+                                        typename hermitian_matrix_element<M2>::value_type>::promote_type promote_type;
+    };
+
+#endif
+    /** \brief A hermitian matrix of values of type \c T
+     *
+     * For a \f$(n \times n)\f$-dimensional matrix and \f$ 0 \leq i < n, 0 \leq j < n\f$, every element 
+     * \f$m_{i,j}\f$ is mapped to the \f$(i.n + j)\f$-th element of the container for row major orientation 
+     * or the \f$(i + j.m)\f$-th element of the container for column major orientation. And 
+     * \f$\forall i,j\f$, \f$m_{i,j} = \overline{m_{i,j}}\f$.
+     *
+     * Orientation and storage can also be specified, otherwise a row major and unbounded array are used. 
+     * It is \b not required by the storage to initialize elements of the matrix. 
+     * Moreover, only the given triangular matrix is stored and the storage of hermitian matrices is packed.
+     *
+     * See http://en.wikipedia.org/wiki/Hermitian_matrix for more details on hermitian matrices.
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+     * \tparam TRI the type of triangular matrix is either \c lower or \c upper. Default is \c lower
+     * \tparam L the storage organization. It is either \c row_major or \c column_major. Default is \c row_major
+     * \tparam A the type of Storage array. Default is \unbounded_array.
+     */
+    template<class T, class TRI, class L, class A>
+    class hermitian_matrix:
+        public matrix_container<hermitian_matrix<T, TRI, L, A> > {
+
+        typedef T &true_reference;
+        typedef T *pointer;
+        typedef TRI triangular_type;
+        typedef L layout_type;
+        typedef hermitian_matrix<T, TRI, L, A> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        // FIXME no better way to not return the address of a temporary?
+        // typedef const T &const_reference;
+        typedef const T const_reference;
+#ifndef BOOST_UBLAS_STRICT_HERMITIAN
+        typedef T &reference;
+#else
+        typedef hermitian_matrix_element<self_type> reference;
+#endif
+        typedef A array_type;
+
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef vector<T, A> vector_temporary_type;
+        typedef matrix<T, L, A> matrix_temporary_type;  // general sub-matrix
+        typedef packed_tag storage_category;
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        hermitian_matrix ():
+            matrix_container<self_type> (),
+            size_ (0), data_ (0) {}
+        BOOST_UBLAS_INLINE
+        hermitian_matrix (size_type size):
+            matrix_container<self_type> (),
+            size_ (BOOST_UBLAS_SAME (size, size)), data_ (triangular_type::packed_size (layout_type (), size, size)) {
+        }
+        BOOST_UBLAS_INLINE
+        hermitian_matrix (size_type size1, size_type size2):
+            matrix_container<self_type> (),
+            size_ (BOOST_UBLAS_SAME (size1, size2)), data_ (triangular_type::packed_size (layout_type (), size1, size2)) {
+        }
+        BOOST_UBLAS_INLINE
+        hermitian_matrix (size_type size, const array_type &data):
+            matrix_container<self_type> (),
+            size_ (size), data_ (data) {}
+        BOOST_UBLAS_INLINE
+        hermitian_matrix (const hermitian_matrix &m):
+            matrix_container<self_type> (),
+            size_ (m.size_), data_ (m.data_) {}
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix (const matrix_expression<AE> &ae):
+            matrix_container<self_type> (),
+            size_ (BOOST_UBLAS_SAME (ae ().size1 (), ae ().size2 ())),
+            data_ (triangular_type::packed_size (layout_type (), size_, size_)) {
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const array_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, bool preserve = true) {
+            if (preserve) {
+                self_type temporary (size, size);
+                detail::matrix_resize_preserve<layout_type, triangular_type> (*this, temporary);
+            }
+            else {
+                data ().resize (triangular_type::packed_size (layout_type (), size, size));
+                size_ = size;
+            }
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            resize (BOOST_UBLAS_SAME (size1, size2), preserve);
+        }
+        BOOST_UBLAS_INLINE
+        void resize_packed_preserve (size_type size) {
+            size_ = BOOST_UBLAS_SAME (size, size);
+            data ().resize (triangular_type::packed_size (layout_type (), size_, size_), value_type ());
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_, bad_index ());
+            // if (i == j)
+            //    return type_traits<value_type>::real (data () [triangular_type::element (layout_type (), i, size_, i, size_)]);
+            // else
+            if (triangular_type::other (i, j))
+                return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
+            else
+                return type_traits<value_type>::conj (data () [triangular_type::element (layout_type (), j, size_, i, size_)]);
+        }
+        BOOST_UBLAS_INLINE
+        true_reference at_element (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_, bad_index ());
+            BOOST_UBLAS_CHECK (triangular_type::other (i, j), bad_index ());
+            return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+#ifndef BOOST_UBLAS_STRICT_HERMITIAN
+            if (!triangular_type::other (i, j)) {
+                bad_index ().raise ();
+                // NEVER reached
+            }
+            return at_element (i, j);
+#else
+        if (triangular_type::other (i, j))
+            return reference (*this, i, j, data () [triangular_type::element (layout_type (), i, size_, j, size_)]);
+        else
+            return reference (*this, i, j, type_traits<value_type>::conj (data () [triangular_type::element (layout_type (), j, size_, i, size_)]));
+#endif
+        }
+
+        // Element assignemnt
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, size_type j, const_reference t) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_, bad_index ());
+            if (triangular_type::other (i, j)) {
+                return (data () [triangular_type::element (layout_type (), i, size_, j, size_)] = t);
+            } else {
+                return (data () [triangular_type::element (layout_type (), j, size_, i, size_)] = type_traits<value_type>::conj (t));
+            }
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_, bad_index ());
+            data () [triangular_type::element (layout_type (), i, size_, j, size_)] = value_type/*zero*/();
+        }
+
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        hermitian_matrix &operator = (const hermitian_matrix &m) {
+            size_ = m.size_;
+            data () = m.data ();
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        hermitian_matrix &assign_temporary (hermitian_matrix &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix& operator *= (const AT &at) {
+            // Multiplication is only allowed for real scalars,
+            // otherwise the resulting matrix isn't hermitian.
+            // Thanks to Peter Schmitteckert for spotting this.
+            BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        hermitian_matrix& operator /= (const AT &at) {
+            // Multiplication is only allowed for real scalars,
+            // otherwise the resulting matrix isn't hermitian.
+            // Thanks to Peter Schmitteckert for spotting this.
+            BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (hermitian_matrix &m) {
+            if (this != &m) {
+                std::swap (size_, m.size_);
+                data ().swap (m.data ());
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (hermitian_matrix &m1, hermitian_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
+            return const_iterator1 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
+            if (rank == 0)
+                i = triangular_type::global_mutable_restrict1 (i, size1(), j, size2());
+            return iterator1 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
+            return const_iterator2 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
+            if (rank == 0)
+                j = triangular_type::global_mutable_restrict2 (i, size1(), j, size2());
+            return iterator2 (*this, i, j);
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<hermitian_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename hermitian_matrix::value_type value_type;
+            typedef typename hermitian_matrix::difference_type difference_type;
+            typedef typename hermitian_matrix::const_reference reference;
+            typedef const typename hermitian_matrix::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, size_type it1, size_type it2):
+                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, it1_, 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<hermitian_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename hermitian_matrix::value_type value_type;
+            typedef typename hermitian_matrix::difference_type difference_type;
+            typedef typename hermitian_matrix::true_reference reference;
+            typedef typename hermitian_matrix::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, size_type it1, size_type it2):
+                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return (*this) ().at_element (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                return (*this) ().find2 (1, it1_, 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size_, 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<hermitian_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename hermitian_matrix::value_type value_type;
+            typedef typename hermitian_matrix::difference_type difference_type;
+            typedef typename hermitian_matrix::const_reference reference;
+            typedef const typename hermitian_matrix::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, size_type it1, size_type it2):
+                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<hermitian_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename hermitian_matrix::value_type value_type;
+            typedef typename hermitian_matrix::difference_type difference_type;
+            typedef typename hermitian_matrix::true_reference reference;
+            typedef typename hermitian_matrix::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, size_type it1, size_type it2):
+                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return (*this) ().at_element (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                return (*this) ().find1 (1, 0, it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        size_type size_;
+        array_type data_;
+    };
+
+    /** \brief A Hermitian matrix adaptator: convert a any matrix into a Hermitian matrix expression
+     *
+     * For a \f$(m\times n)\f$-dimensional matrix, the \c hermitian_adaptor will provide a hermitian matrix.
+     * Storage and location are based on those of the underlying matrix. This is important because
+     * a \c hermitian_adaptor does not copy the matrix data to a new place. Therefore, modifying values
+     * in a \c hermitian_adaptor matrix will also modify the underlying matrix too.
+     *
+     * \tparam M the type of matrix used to generate a hermitian matrix
+     */
+    template<class M, class TRI>
+    class hermitian_adaptor:
+        public matrix_expression<hermitian_adaptor<M, TRI> > {
+
+        typedef hermitian_adaptor<M, TRI> self_type;
+        typedef typename M::value_type &true_reference;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef const M const_matrix_type;
+        typedef M matrix_type;
+        typedef TRI triangular_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::value_type const_reference;
+#ifndef BOOST_UBLAS_STRICT_HERMITIAN
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::value_type,
+                                          typename M::reference>::type reference;
+#else
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::value_type,
+                                          hermitian_matrix_element<self_type> >::type reference;
+#endif
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        // Replaced by _temporary_traits to avoid type requirements on M
+        //typedef typename M::vector_temporary_type vector_temporary_type;
+        //typedef typename M::matrix_temporary_type matrix_temporary_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 packed_proxy_tag>::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor (matrix_type &data):
+            matrix_expression<self_type> (),
+            data_ (data) {
+            BOOST_UBLAS_CHECK (data_.size1 () == data_.size2 (), bad_size ());
+        }
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor (const hermitian_adaptor &m):
+            matrix_expression<self_type> (),
+            data_ (m.data_) {
+            BOOST_UBLAS_CHECK (data_.size1 () == data_.size2 (), bad_size ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return data_.size1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return data_.size2 ();
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+            // if (i == j)
+            //     return type_traits<value_type>::real (data () (i, i));
+            // else
+            if (triangular_type::other (i, j))
+                return data () (i, j);
+            else
+                return type_traits<value_type>::conj (data () (j, i));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+#ifndef BOOST_UBLAS_STRICT_HERMITIAN
+            if (triangular_type::other (i, j))
+                return data () (i, j);
+            else {
+                external_logic ().raise ();
+                return conj_ = type_traits<value_type>::conj (data () (j, i));
+            }
+#else
+            if (triangular_type::other (i, j))
+                return reference (*this, i, j, data () (i, j));
+            else
+                return reference (*this, i, j, type_traits<value_type>::conj (data () (j, i)));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, size_type j, value_type t) {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+            // if (i == j)
+            //     data () (i, i) = type_traits<value_type>::real (t);
+            // else
+            if (triangular_type::other (i, j))
+                return data () (i, j) = t;
+            else
+                return data () (j, i) = type_traits<value_type>::conj (t);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+#ifndef BOOST_UBLAS_STRICT_HERMITIAN
+            if (triangular_type::other (i, j))
+                return data () (i, j);
+            else {
+                external_logic ().raise ();
+                return conj_ = type_traits<value_type>::conj (data () (j, i));
+            }
+#else
+            if (triangular_type::other (i, j))
+                return reference (*this, i, j, data () (i, j));
+            else
+                return reference (*this, i, j, type_traits<value_type>::conj (data () (j, i)));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, size_type j, value_type t) {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+            // if (i == j)
+            //     data () (i, i) = type_traits<value_type>::real (t);
+            // else
+            if (triangular_type::other (i, j))
+                return data () (i, j) = t;
+            else
+                return data () (j, i) = type_traits<value_type>::conj (t);
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor &operator = (const hermitian_adaptor &m) {
+            matrix_assign<scalar_assign, triangular_type> (*this, m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor &assign_temporary (hermitian_adaptor &m) {
+            *this = m;
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor &operator = (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign, triangular_type> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor& operator += (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign, triangular_type> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor& operator -= (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign, triangular_type> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor& operator *= (const AT &at) {
+            // Multiplication is only allowed for real scalars,
+            // otherwise the resulting matrix isn't hermitian.
+            // Thanks to Peter Schmitteckert for spotting this.
+            BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        hermitian_adaptor& operator /= (const AT &at) {
+            // Multiplication is only allowed for real scalars,
+            // otherwise the resulting matrix isn't hermitian.
+            // Thanks to Peter Schmitteckert for spotting this.
+            BOOST_UBLAS_CHECK (type_traits<value_type>::imag (at) == 0, non_real ());
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const hermitian_adaptor &ha) const {
+            return (*this).data ().same_closure (ha.data ());
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (hermitian_adaptor &m) {
+            if (this != &m)
+                matrix_swap<scalar_swap, triangular_type> (*this, m);
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (hermitian_adaptor &m1, hermitian_adaptor &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use matrix iterator
+        typedef typename M::const_iterator1 const_subiterator1_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator1,
+                                          typename M::iterator1>::type subiterator1_type;
+        typedef typename M::const_iterator2 const_subiterator2_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator2,
+                                          typename M::iterator2>::type subiterator2_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            if (triangular_type::other (i, j)) {
+                if (triangular_type::other (size1 (), j)) {
+                    return const_iterator1 (*this, 0, 0,
+                                            data ().find1 (rank, i, j), data ().find1 (rank, size1 (), j),
+                                            data ().find2 (rank, size2 (), size1 ()), data ().find2 (rank, size2 (), size1 ()));
+                } else {
+                    return const_iterator1 (*this, 0, 1,
+                                            data ().find1 (rank, i, j), data ().find1 (rank, j, j),
+                                            data ().find2 (rank, j, j), data ().find2 (rank, j, size1 ()));
+                }
+            } else {
+                if (triangular_type::other (size1 (), j)) {
+                    return const_iterator1 (*this, 1, 0,
+                                            data ().find1 (rank, j, j), data ().find1 (rank, size1 (), j),
+                                            data ().find2 (rank, j, i), data ().find2 (rank, j, j));
+                } else {
+                    return const_iterator1 (*this, 1, 1,
+                                            data ().find1 (rank, size1 (), size2 ()), data ().find1 (rank, size1 (), size2 ()),
+                                            data ().find2 (rank, j, i), data ().find2 (rank, j, size1 ()));
+                }
+            }
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
+            if (rank == 0)
+                i = triangular_type::global_mutable_restrict1 (i, size1(), j, size2());
+            return iterator1 (*this, data ().find1 (rank, i, j));
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            if (triangular_type::other (i, j)) {
+                if (triangular_type::other (i, size2 ())) {
+                    return const_iterator2 (*this, 1, 1,
+                                            data ().find1 (rank, size2 (), size1 ()), data ().find1 (rank, size2 (), size1 ()),
+                                            data ().find2 (rank, i, j), data ().find2 (rank, i, size2 ()));
+                } else {
+                    return const_iterator2 (*this, 1, 0,
+                                            data ().find1 (rank, i, i), data ().find1 (rank, size2 (), i),
+                                            data ().find2 (rank, i, j), data ().find2 (rank, i, i));
+                }
+            } else {
+                if (triangular_type::other (i, size2 ())) {
+                    return const_iterator2 (*this, 0, 1,
+                                            data ().find1 (rank, j, i), data ().find1 (rank, i, i),
+                                            data ().find2 (rank, i, i), data ().find2 (rank, i, size2 ()));
+                } else {
+                    return const_iterator2 (*this, 0, 0,
+                                            data ().find1 (rank, j, i), data ().find1 (rank, size2 (), i),
+                                            data ().find2 (rank, size1 (), size2 ()), data ().find2 (rank, size2 (), size2 ()));
+                }
+            }
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
+            if (rank == 0)
+                j = triangular_type::global_mutable_restrict2 (i, size1(), j, size2());
+            return iterator2 (*this, data ().find2 (rank, i, j));
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<hermitian_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename const_subiterator1_type::iterator_category, dense_random_access_iterator_tag>::iterator_category,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename const_subiterator1_type::value_type value_type;
+            typedef typename const_subiterator1_type::difference_type difference_type;
+            // FIXME no better way to not return the address of a temporary?
+            // typedef typename const_subiterator1_type::reference reference;
+            typedef typename const_subiterator1_type::value_type reference;
+            typedef typename const_subiterator1_type::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (),
+                begin_ (-1), end_ (-1), current_ (-1),
+                it1_begin_ (), it1_end_ (), it1_ (),
+                it2_begin_ (), it2_end_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, int begin, int end,
+                             const const_subiterator1_type &it1_begin, const const_subiterator1_type &it1_end,
+                             const const_subiterator2_type &it2_begin, const const_subiterator2_type &it2_end):
+                container_const_reference<self_type> (m),
+                begin_ (begin), end_ (end), current_ (begin),
+                it1_begin_ (it1_begin), it1_end_ (it1_end), it1_ (it1_begin_),
+                it2_begin_ (it2_begin), it2_end_ (it2_end), it2_ (it2_begin_) {
+                if (current_ == 0 && it1_ == it1_end_)
+                    current_ = 1;
+                if (current_ == 1 && it2_ == it2_end_)
+                    current_ = 0;
+                if ((current_ == 0 && it1_ == it1_end_) ||
+                    (current_ == 1 && it2_ == it2_end_))
+                    current_ = end_;
+                BOOST_UBLAS_CHECK (current_ == end_ ||
+                                   (current_ == 0 && it1_ != it1_end_) ||
+                                   (current_ == 1 && it2_ != it2_end_), internal_logic ());
+            }
+            // FIXME cannot compile
+            //  iterator1 does not have these members!
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()),
+                begin_ (it.begin_), end_ (it.end_), current_ (it.current_),
+                it1_begin_ (it.it1_begin_), it1_end_ (it.it1_end_), it1_ (it.it1_),
+                it2_begin_ (it.it2_begin_), it2_end_ (it.it2_end_), it2_ (it.it2_) {
+                BOOST_UBLAS_CHECK (current_ == end_ ||
+                                   (current_ == 0 && it1_ != it1_end_) ||
+                                   (current_ == 1 && it2_ != it2_end_), internal_logic ());
+            }
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    ++ it1_;
+                    if (it1_ == it1_end_ && end_ == 1) {
+                        it2_ = it2_begin_;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    ++ it2_;
+                    if (it2_ == it2_end_ && end_ == 0) {
+                        it1_ = it1_begin_;
+                        current_ = 0;
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    if (it1_ == it1_begin_ && begin_ == 1) {
+                        it2_ = it2_end_;
+                        BOOST_UBLAS_CHECK (it2_ != it2_begin_, internal_logic ());
+                        -- it2_;
+                        current_ = 1;
+                    } else {
+                        -- it1_;
+                    }
+                } else /* if (current_ == 1) */ {
+                    if (it2_ == it2_begin_ && begin_ == 0) {
+                        it1_ = it1_end_;
+                        BOOST_UBLAS_CHECK (it1_ != it1_begin_, internal_logic ());
+                        -- it1_;
+                        current_ = 0;
+                    } else {
+                        -- it2_;
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    size_type d = (std::min) (n, it1_end_ - it1_);
+                    it1_ += d;
+                    n -= d;
+                    if (n > 0 || (end_ == 1 && it1_ == it1_end_)) {
+                        BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
+                        d = (std::min) (n, it2_end_ - it2_begin_);
+                        it2_ = it2_begin_ + d;
+                        n -= d;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    size_type d = (std::min) (n, it2_end_ - it2_);
+                    it2_ += d;
+                    n -= d;
+                    if (n > 0 || (end_ == 0 && it2_ == it2_end_)) {
+                        BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
+                        d = (std::min) (n, it1_end_ - it1_begin_);
+                        it1_ = it1_begin_ + d;
+                        n -= d;
+                        current_ = 0;
+                    }
+                }
+                BOOST_UBLAS_CHECK (n == 0, external_logic ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    size_type d = (std::min) (n, it1_ - it1_begin_);
+                    it1_ -= d;
+                    n -= d;
+                    if (n > 0) {
+                        BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
+                        d = (std::min) (n, it2_end_ - it2_begin_);
+                        it2_ = it2_end_ - d;
+                        n -= d;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    size_type d = (std::min) (n, it2_ - it2_begin_);
+                    it2_ -= d;
+                    n -= d;
+                    if (n > 0) {
+                        BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
+                        d = (std::min) (n, it1_end_ - it1_begin_);
+                        it1_ = it1_end_ - d;
+                        n -= d;
+                        current_ = 0;
+                    }
+                }
+                BOOST_UBLAS_CHECK (n == 0, external_logic ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
+                if (current_ == 0 && it.current_ == 0) {
+                    return it1_ - it.it1_;
+                } else if (current_ == 0 && it.current_ == 1) {
+                    if (end_ == 1 && it.end_ == 1) {
+                        return (it1_ - it.it1_end_) + (it.it2_begin_ - it.it2_);
+                    } else /* if (end_ == 0 && it.end_ == 0) */ {
+                        return (it1_ - it.it1_begin_) + (it.it2_end_ - it.it2_);
+                    }
+
+                } else if (current_ == 1 && it.current_ == 0) {
+                    if (end_ == 1 && it.end_ == 1) {
+                        return (it2_ - it.it2_begin_) + (it.it1_end_ - it.it1_);
+                    } else /* if (end_ == 0 && it.end_ == 0) */ {
+                        return (it2_ - it.it2_end_) + (it.it1_begin_ - it.it1_);
+                    }
+                } else /* if (current_ == 1 && it.current_ == 1) */ {
+                    return it2_ - it.it2_;
+                }
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    if (triangular_type::other (index1 (), index2 ()))
+                        return *it1_;
+                    else
+                        return type_traits<value_type>::conj (*it1_);
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    if (triangular_type::other (index1 (), index2 ()))
+                        return *it2_;
+                    else
+                        return type_traits<value_type>::conj (*it2_);
+                }
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    return it1_.index1 ();
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    return it2_.index2 ();
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    return it1_.index2 ();
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    return it2_.index1 ();
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                begin_ = it.begin_;
+                end_ = it.end_;
+                current_ = it.current_;
+                it1_begin_ = it.it1_begin_;
+                it1_end_ = it.it1_end_;
+                it1_ = it.it1_;
+                it2_begin_ = it.it2_begin_;
+                it2_end_ = it.it2_end_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
+                return (current_ == 0 && it.current_ == 0 && it1_ == it.it1_) ||
+                       (current_ == 1 && it.current_ == 1 && it2_ == it.it2_);
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it - *this > 0;
+            }
+
+        private:
+            int begin_;
+            int end_;
+            int current_;
+            const_subiterator1_type it1_begin_;
+            const_subiterator1_type it1_end_;
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_begin_;
+            const_subiterator2_type it2_end_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<hermitian_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               iterator1, value_type> {
+        public:
+            typedef typename subiterator1_type::value_type value_type;
+            typedef typename subiterator1_type::difference_type difference_type;
+            typedef typename subiterator1_type::reference reference;
+            typedef typename subiterator1_type::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it1_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, const subiterator1_type &it1):
+                container_reference<self_type> (m), it1_ (it1) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return *it1_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it1_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            subiterator1_type it1_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1 (), 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<hermitian_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+            typename const_subiterator2_type::iterator_category, dense_random_access_iterator_tag>::iterator_category,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename const_subiterator2_type::value_type value_type;
+            typedef typename const_subiterator2_type::difference_type difference_type;
+            // FIXME no better way to not return the address of a temporary?
+            // typedef typename const_subiterator2_type::reference reference;
+            typedef typename const_subiterator2_type::value_type reference;
+            typedef typename const_subiterator2_type::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (),
+                begin_ (-1), end_ (-1), current_ (-1),
+                it1_begin_ (), it1_end_ (), it1_ (),
+                it2_begin_ (), it2_end_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, int begin, int end,
+                             const const_subiterator1_type &it1_begin, const const_subiterator1_type &it1_end,
+                             const const_subiterator2_type &it2_begin, const const_subiterator2_type &it2_end):
+                container_const_reference<self_type> (m),
+                begin_ (begin), end_ (end), current_ (begin),
+                it1_begin_ (it1_begin), it1_end_ (it1_end), it1_ (it1_begin_),
+                it2_begin_ (it2_begin), it2_end_ (it2_end), it2_ (it2_begin_) {
+                if (current_ == 0 && it1_ == it1_end_)
+                    current_ = 1;
+                if (current_ == 1 && it2_ == it2_end_)
+                    current_ = 0;
+                if ((current_ == 0 && it1_ == it1_end_) ||
+                    (current_ == 1 && it2_ == it2_end_))
+                    current_ = end_;
+                BOOST_UBLAS_CHECK (current_ == end_ ||
+                                   (current_ == 0 && it1_ != it1_end_) ||
+                                   (current_ == 1 && it2_ != it2_end_), internal_logic ());
+            }
+            // FIXME cannot compiler
+            //  iterator2 does not have these members!
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()),
+                begin_ (it.begin_), end_ (it.end_), current_ (it.current_),
+                it1_begin_ (it.it1_begin_), it1_end_ (it.it1_end_), it1_ (it.it1_),
+                it2_begin_ (it.it2_begin_), it2_end_ (it.it2_end_), it2_ (it.it2_) {
+                BOOST_UBLAS_CHECK (current_ == end_ ||
+                                   (current_ == 0 && it1_ != it1_end_) ||
+                                   (current_ == 1 && it2_ != it2_end_), internal_logic ());
+            }
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    ++ it1_;
+                    if (it1_ == it1_end_ && end_ == 1) {
+                        it2_ = it2_begin_;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    ++ it2_;
+                    if (it2_ == it2_end_ && end_ == 0) {
+                        it1_ = it1_begin_;
+                        current_ = 0;
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    if (it1_ == it1_begin_ && begin_ == 1) {
+                        it2_ = it2_end_;
+                        BOOST_UBLAS_CHECK (it2_ != it2_begin_, internal_logic ());
+                        -- it2_;
+                        current_ = 1;
+                    } else {
+                        -- it1_;
+                    }
+                } else /* if (current_ == 1) */ {
+                    if (it2_ == it2_begin_ && begin_ == 0) {
+                        it1_ = it1_end_;
+                        BOOST_UBLAS_CHECK (it1_ != it1_begin_, internal_logic ());
+                        -- it1_;
+                        current_ = 0;
+                    } else {
+                        -- it2_;
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    size_type d = (std::min) (n, it1_end_ - it1_);
+                    it1_ += d;
+                    n -= d;
+                    if (n > 0 || (end_ == 1 && it1_ == it1_end_)) {
+                        BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
+                        d = (std::min) (n, it2_end_ - it2_begin_);
+                        it2_ = it2_begin_ + d;
+                        n -= d;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    size_type d = (std::min) (n, it2_end_ - it2_);
+                    it2_ += d;
+                    n -= d;
+                    if (n > 0 || (end_ == 0 && it2_ == it2_end_)) {
+                        BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
+                        d = (std::min) (n, it1_end_ - it1_begin_);
+                        it1_ = it1_begin_ + d;
+                        n -= d;
+                        current_ = 0;
+                    }
+                }
+                BOOST_UBLAS_CHECK (n == 0, external_logic ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    size_type d = (std::min) (n, it1_ - it1_begin_);
+                    it1_ -= d;
+                    n -= d;
+                    if (n > 0) {
+                        BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
+                        d = (std::min) (n, it2_end_ - it2_begin_);
+                        it2_ = it2_end_ - d;
+                        n -= d;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    size_type d = (std::min) (n, it2_ - it2_begin_);
+                    it2_ -= d;
+                    n -= d;
+                    if (n > 0) {
+                        BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
+                        d = (std::min) (n, it1_end_ - it1_begin_);
+                        it1_ = it1_end_ - d;
+                        n -= d;
+                        current_ = 0;
+                    }
+                }
+                BOOST_UBLAS_CHECK (n == 0, external_logic ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
+                if (current_ == 0 && it.current_ == 0) {
+                    return it1_ - it.it1_;
+                } else if (current_ == 0 && it.current_ == 1) {
+                    if (end_ == 1 && it.end_ == 1) {
+                        return (it1_ - it.it1_end_) + (it.it2_begin_ - it.it2_);
+                    } else /* if (end_ == 0 && it.end_ == 0) */ {
+                        return (it1_ - it.it1_begin_) + (it.it2_end_ - it.it2_);
+                    }
+
+                } else if (current_ == 1 && it.current_ == 0) {
+                    if (end_ == 1 && it.end_ == 1) {
+                        return (it2_ - it.it2_begin_) + (it.it1_end_ - it.it1_);
+                    } else /* if (end_ == 0 && it.end_ == 0) */ {
+                        return (it2_ - it.it2_end_) + (it.it1_begin_ - it.it1_);
+                    }
+                } else /* if (current_ == 1 && it.current_ == 1) */ {
+                    return it2_ - it.it2_;
+                }
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    if (triangular_type::other (index1 (), index2 ()))
+                        return *it1_;
+                    else
+                        return type_traits<value_type>::conj (*it1_);
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    if (triangular_type::other (index1 (), index2 ()))
+                        return *it2_;
+                    else
+                        return type_traits<value_type>::conj (*it2_);
+                }
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return end ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    return it1_.index2 ();
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    return it2_.index1 ();
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    return it1_.index1 ();
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    return it2_.index2 ();
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                begin_ = it.begin_;
+                end_ = it.end_;
+                current_ = it.current_;
+                it1_begin_ = it.it1_begin_;
+                it1_end_ = it.it1_end_;
+                it1_ = it.it1_;
+                it2_begin_ = it.it2_begin_;
+                it2_end_ = it.it2_end_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
+                return (current_ == 0 && it.current_ == 0 && it1_ == it.it1_) ||
+                       (current_ == 1 && it.current_ == 1 && it2_ == it.it2_);
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it - *this > 0;
+            }
+
+        private:
+            int begin_;
+            int end_;
+            int current_;
+            const_subiterator1_type it1_begin_;
+            const_subiterator1_type it1_end_;
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_begin_;
+            const_subiterator2_type it2_end_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<hermitian_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               iterator2, value_type> {
+        public:
+            typedef typename subiterator2_type::value_type value_type;
+            typedef typename subiterator2_type::difference_type difference_type;
+            typedef typename subiterator2_type::reference reference;
+            typedef typename subiterator2_type::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, const subiterator2_type &it2):
+                container_reference<self_type> (m), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return *it2_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it2_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            subiterator2_type it2_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2 ());
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        static value_type conj_;
+    };
+
+    template<class M, class TRI>
+    typename hermitian_adaptor<M, TRI>::value_type hermitian_adaptor<M, TRI>::conj_;
+
+    // Specialization for temporary_traits
+    template <class M, class TRI>
+    struct vector_temporary_traits< hermitian_adaptor<M, TRI> >
+    : vector_temporary_traits< M > {} ;
+    template <class M, class TRI>
+    struct vector_temporary_traits< const hermitian_adaptor<M, TRI> >
+    : vector_temporary_traits< M > {} ;
+
+    template <class M, class TRI>
+    struct matrix_temporary_traits< hermitian_adaptor<M, TRI> >
+    : matrix_temporary_traits< M > {} ;
+    template <class M, class TRI>
+    struct matrix_temporary_traits< const hermitian_adaptor<M, TRI> >
+    : matrix_temporary_traits< M > {} ;
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/io.hpp b/include/boost/numeric/ublas/io.hpp
new file mode 100644
index 0000000..1dee6af
--- /dev/null
+++ b/include/boost/numeric/ublas/io.hpp
@@ -0,0 +1,355 @@
+//
+//  Copyright (c) 2000-2010
+//  Joerg Walter, Mathias Koch, David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_IO_
+#define _BOOST_UBLAS_IO_
+
+// Only forward definition required to define stream operations
+#include <iosfwd>
+#include <sstream>
+#include <boost/numeric/ublas/matrix_expression.hpp>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    /** \brief output stream operator for vector expressions
+     *
+     * Any vector expressions can be written to a standard output stream
+     * as defined in the C++ standard library. For example:
+     * \code
+     * vector<float> v1(3),v2(3);
+     * for(size_t i=0; i<3; i++)
+     * {
+     *       v1(i) = i+0.2;
+     *       v2(i) = i+0.3;
+     * }
+     * cout << v1+v2 << endl;
+     * \endcode
+     * will display the some of the 2 vectors like this:
+     * \code
+     * [3](0.5,2.5,4.5)
+     * \endcode
+     *
+     * \param os is a standard basic output stream
+     * \param v is a vector expression
+     * \return a reference to the resulting output stream
+     */
+    template<class E, class T, class VE>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
+                                           const vector_expression<VE> &v) {
+        typedef typename VE::size_type size_type;
+        size_type size = v ().size ();
+        std::basic_ostringstream<E, T, std::allocator<E> > s;
+        s.flags (os.flags ());
+        s.imbue (os.getloc ());
+        s.precision (os.precision ());
+        s << '[' << size << "](";
+        if (size > 0)
+            s << v () (0);
+        for (size_type i = 1; i < size; ++ i)
+            s << ',' << v () (i);
+        s << ')';
+        return os << s.str ().c_str ();
+    }
+
+    /** \brief input stream operator for vectors
+     *
+     * This is used to feed in vectors with data stored as an ASCII representation
+     * from a standard input stream.
+     *
+     * From a file or any valid stream, the format is: 
+     * \c [<vector size>](<data1>,<data2>,...<dataN>) like for example:
+     * \code
+     * [5](1,2.1,3.2,3.14,0.2)
+     * \endcode
+     *
+     * You can use it like this
+     * \code
+     * my_input_stream >> my_vector;
+     * \endcode
+     *
+     * You can only put data into a valid \c vector<> not a \c vector_expression
+     *
+     * \param is is a standard basic input stream
+     * \param v is a vector
+     * \return a reference to the resulting input stream
+     */
+    template<class E, class T, class VT, class VA>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
+                                           vector<VT, VA> &v) {
+        typedef typename vector<VT, VA>::size_type size_type;
+        E ch;
+        size_type size;
+        if (is >> ch && ch != '[') {
+            is.putback (ch);
+            is.setstate (std::ios_base::failbit);
+        } else if (is >> size >> ch && ch != ']') {
+            is.putback (ch);
+            is.setstate (std::ios_base::failbit);
+        } else if (! is.fail ()) {
+            vector<VT, VA> s (size);
+            if (is >> ch && ch != '(') {
+                is.putback (ch);
+                is.setstate (std::ios_base::failbit);
+            } else if (! is.fail ()) {
+                for (size_type i = 0; i < size; i ++) {
+                    if (is >> s (i) >> ch && ch != ',') {
+                        is.putback (ch);
+                        if (i < size - 1)
+                            is.setstate (std::ios_base::failbit);
+                        break;
+                    }
+                }
+                if (is >> ch && ch != ')') {
+                    is.putback (ch);
+                    is.setstate (std::ios_base::failbit);
+                }
+            }
+            if (! is.fail ())
+                v.swap (s);
+        }
+        return is;
+    }
+
+    /** \brief output stream operator for matrix expressions
+     *
+     * it outpus the content of a \f$(M \times N)\f$ matrix to a standard output 
+     * stream using the following format:
+     * \c[<rows>,<columns>]((<m00>,<m01>,...,<m0N>),...,(<mM0>,<mM1>,...,<mMN>))
+     *
+     * For example:
+     * \code
+     * matrix<float> m(3,3) = scalar_matrix<float>(3,3,1.0) - diagonal_matrix<float>(3,3,1.0);
+     * cout << m << endl;
+     * \encode
+     * will display
+     * \code
+     * [3,3]((0,1,1),(1,0,1),(1,1,0))
+     * \endcode
+     * This output is made for storing and retrieving matrices in a simple way but you can
+     * easily recognize the following: 
+     * \f[ \left( \begin{array}{ccc} 1 & 1 & 1\\ 1 & 1 & 1\\ 1 & 1 & 1 \end{array} \right) - \left( \begin{array}{ccc} 1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1 \end{array} \right) = \left( \begin{array}{ccc} 0 & 1 & 1\\ 1 & 0 & 1\\ 1 & 1 & 0 \end{array} \right) \f]
+     *
+     * \param os is a standard basic output stream
+     * \param m is a matrix expression
+     * \return a reference to the resulting output stream
+     */
+    template<class E, class T, class ME>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
+                                           const matrix_expression<ME> &m) {
+        typedef typename ME::size_type size_type;
+        size_type size1 = m ().size1 ();
+        size_type size2 = m ().size2 ();
+        std::basic_ostringstream<E, T, std::allocator<E> > s;
+        s.flags (os.flags ());
+        s.imbue (os.getloc ());
+        s.precision (os.precision ());
+        s << '[' << size1 << ',' << size2 << "](";
+        if (size1 > 0) {
+            s << '(' ;
+            if (size2 > 0)
+                s << m () (0, 0);
+            for (size_type j = 1; j < size2; ++ j)
+                s << ',' << m () (0, j);
+            s << ')';
+        }
+        for (size_type i = 1; i < size1; ++ i) {
+            s << ",(" ;
+            if (size2 > 0)
+                s << m () (i, 0);
+            for (size_type j = 1; j < size2; ++ j)
+                s << ',' << m () (i, j);
+            s << ')';
+        }
+        s << ')';
+        return os << s.str ().c_str ();
+    }
+
+    /** \brief input stream operator for matrices
+     *
+     * This is used to feed in matrices with data stored as an ASCII representation
+     * from a standard input stream.
+     *
+     * From a file or any valid standard stream, the format is:
+     * \c[<rows>,<columns>]((<m00>,<m01>,...,<m0N>),...,(<mM0>,<mM1>,...,<mMN>))
+     *
+     * You can use it like this
+     * \code
+     * my_input_stream >> my_matrix;
+     * \endcode
+     *
+     * You can only put data into a valid \c matrix<> not a \c matrix_expression
+     *
+     * \param is is a standard basic input stream
+     * \param m is a matrix
+     * \return a reference to the resulting input stream
+     */
+    template<class E, class T, class MT, class MF, class MA>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
+                                           matrix<MT, MF, MA> &m) {
+        typedef typename matrix<MT, MF, MA>::size_type size_type;
+        E ch;
+        size_type size1, size2;
+        if (is >> ch && ch != '[') {
+            is.putback (ch);
+            is.setstate (std::ios_base::failbit);
+        } else if (is >> size1 >> ch && ch != ',') {
+            is.putback (ch);
+            is.setstate (std::ios_base::failbit);
+        } else if (is >> size2 >> ch && ch != ']') {
+            is.putback (ch);
+            is.setstate (std::ios_base::failbit);
+        } else if (! is.fail ()) {
+            matrix<MT, MF, MA> s (size1, size2);
+            if (is >> ch && ch != '(') {
+                is.putback (ch);
+                is.setstate (std::ios_base::failbit);
+            } else if (! is.fail ()) {
+                for (size_type i = 0; i < size1; i ++) {
+                    if (is >> ch && ch != '(') {
+                        is.putback (ch);
+                        is.setstate (std::ios_base::failbit);
+                        break;
+                    }
+                    for (size_type j = 0; j < size2; j ++) {
+                        if (is >> s (i, j) >> ch && ch != ',') {
+                            is.putback (ch);
+                            if (j < size2 - 1) {
+                                is.setstate (std::ios_base::failbit);
+                                break;
+                            }
+                        }
+                    }
+                    if (is >> ch && ch != ')') {
+                        is.putback (ch);
+                        is.setstate (std::ios_base::failbit);
+                        break;
+                    }
+                    if (is >> ch && ch != ',') {
+                       is.putback (ch);
+                       if (i < size1 - 1) {
+                            is.setstate (std::ios_base::failbit);
+                            break;
+                       }
+                    }
+                }
+                if (is >> ch && ch != ')') {
+                    is.putback (ch);
+                    is.setstate (std::ios_base::failbit);
+                }
+            }
+            if (! is.fail ())
+                m.swap (s);
+        }
+        return is;
+    }
+
+    /** \brief special input stream operator for symmetric matrices
+     *
+     * This is used to feed in symmetric matrices with data stored as an ASCII 
+     * representation from a standard input stream.
+     *
+     * You can simply write your matrices in a file or any valid stream and read them again 
+     * at a later time with this function. The format is the following:
+     * \code [<rows>,<columns>]((<m00>,<m01>,...,<m0N>),...,(<mM0>,<mM1>,...,<mMN>)) \endcode
+     *
+     * You can use it like this
+     * \code
+     * my_input_stream >> my_symmetric_matrix;
+     * \endcode
+     *
+     * You can only put data into a valid \c symmetric_matrix<>, not in a \c matrix_expression
+     * This function also checks that input data form a valid symmetric matrix
+     *
+     * \param is is a standard basic input stream
+     * \param m is a \c symmetric_matrix
+     * \return a reference to the resulting input stream
+     */
+    template<class E, class T, class MT, class MF1, class MF2, class MA>
+    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+    std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
+                                           symmetric_matrix<MT, MF1, MF2, MA> &m) {
+        typedef typename symmetric_matrix<MT, MF1, MF2, MA>::size_type size_type;
+        E ch;
+        size_type size1, size2;
+        MT value;
+        if (is >> ch && ch != '[') {
+            is.putback (ch);
+            is.setstate (std::ios_base::failbit);
+        } else if (is >> size1 >> ch && ch != ',') {
+            is.putback (ch);
+            is.setstate (std::ios_base::failbit);
+        } else if (is >> size2 >> ch && (size2 != size1 || ch != ']')) { // symmetric matrix must be square
+            is.putback (ch);
+            is.setstate (std::ios_base::failbit);
+        } else if (! is.fail ()) {
+            symmetric_matrix<MT, MF1, MF2, MA> s (size1, size2);
+            if (is >> ch && ch != '(') {
+                is.putback (ch);
+                is.setstate (std::ios_base::failbit);
+             } else if (! is.fail ()) {
+                for (size_type i = 0; i < size1; i ++) {
+                    if (is >> ch && ch != '(') {
+                        is.putback (ch);
+                        is.setstate (std::ios_base::failbit);
+                        break;
+                    }
+                    for (size_type j = 0; j < size2; j ++) {
+                        if (is >> value >> ch && ch != ',') {
+                            is.putback (ch);
+                            if (j < size2 - 1) {
+                                is.setstate (std::ios_base::failbit);
+                                break;
+                            }
+                        }
+                        if (i <= j) { 
+                             // this is the first time we read this element - set the value
+                            s(i,j) = value;
+                        }
+                        else if ( s(i,j) != value ) {
+                            // matrix is not symmetric
+                            is.setstate (std::ios_base::failbit);
+                            break;
+                        }
+                     }
+                     if (is >> ch && ch != ')') {
+                         is.putback (ch);
+                         is.setstate (std::ios_base::failbit);
+                         break;
+                     }
+                     if (is >> ch && ch != ',') {
+                        is.putback (ch);
+                        if (i < size1 - 1) {
+                             is.setstate (std::ios_base::failbit);
+                             break;
+                        }
+                     }
+                }
+                if (is >> ch && ch != ')') {
+                    is.putback (ch);
+                    is.setstate (std::ios_base::failbit);
+                }
+            }
+            if (! is.fail ())
+                m.swap (s);
+        }
+        return is;
+    }
+ 
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/lu.hpp b/include/boost/numeric/ublas/lu.hpp
new file mode 100644
index 0000000..59544a3
--- /dev/null
+++ b/include/boost/numeric/ublas/lu.hpp
@@ -0,0 +1,350 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_LU_
+#define _BOOST_UBLAS_LU_
+
+#include <boost/numeric/ublas/operation.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+
+// LU factorizations in the spirit of LAPACK and Golub & van Loan
+
+namespace boost { namespace numeric { namespace ublas {
+
+    /** \brief
+     *
+     * \tparam T
+     * \tparam A
+     */
+    template<class T = std::size_t, class A = unbounded_array<T> >
+    class permutation_matrix:
+        public vector<T, A> {
+    public:
+        typedef vector<T, A> vector_type;
+        typedef typename vector_type::size_type size_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        explicit
+        permutation_matrix (size_type size):
+            vector<T, A> (size) {
+            for (size_type i = 0; i < size; ++ i)
+                (*this) (i) = i;
+        }
+        BOOST_UBLAS_INLINE
+        explicit
+        permutation_matrix (const vector_type & init) 
+            : vector_type(init)
+        { }
+        BOOST_UBLAS_INLINE
+        ~permutation_matrix () {}
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        permutation_matrix &operator = (const permutation_matrix &m) {
+            vector_type::operator = (m);
+            return *this;
+        }
+    };
+
+    template<class PM, class MV>
+    BOOST_UBLAS_INLINE
+    void swap_rows (const PM &pm, MV &mv, vector_tag) {
+        typedef typename PM::size_type size_type;
+
+        size_type size = pm.size ();
+        for (size_type i = 0; i < size; ++ i) {
+            if (i != pm (i))
+                std::swap (mv (i), mv (pm (i)));
+        }
+    }
+    template<class PM, class MV>
+    BOOST_UBLAS_INLINE
+    void swap_rows (const PM &pm, MV &mv, matrix_tag) {
+        typedef typename PM::size_type size_type;
+
+        size_type size = pm.size ();
+        for (size_type i = 0; i < size; ++ i) {
+            if (i != pm (i))
+                row (mv, i).swap (row (mv, pm (i)));
+        }
+    }
+    // Dispatcher
+    template<class PM, class MV>
+    BOOST_UBLAS_INLINE
+    void swap_rows (const PM &pm, MV &mv) {
+        swap_rows (pm, mv, typename MV::type_category ());
+    }
+
+    // LU factorization without pivoting
+    template<class M>
+    typename M::size_type lu_factorize (M &m) {
+
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef M matrix_type;
+        matrix_type cm (m);
+#endif
+        size_type singular = 0;
+        size_type size1 = m.size1 ();
+        size_type size2 = m.size2 ();
+        size_type size = (std::min) (size1, size2);
+        for (size_type i = 0; i < size; ++ i) {
+            matrix_column<M> mci (column (m, i));
+            matrix_row<M> mri (row (m, i));
+            if (m (i, i) != value_type/*zero*/()) {
+                value_type m_inv = value_type (1) / m (i, i);
+                project (mci, range (i + 1, size1)) *= m_inv;
+            } else if (singular == 0) {
+                singular = i + 1;
+            }
+            project (m, range (i + 1, size1), range (i + 1, size2)).minus_assign (
+                outer_prod (project (mci, range (i + 1, size1)),
+                            project (mri, range (i + 1, size2))));
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (singular != 0 ||
+                           detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
+                                                                triangular_adaptor<matrix_type, upper> (m)), 
+                                                          cm), internal_logic ());
+#endif
+        return singular;
+    }
+
+    // LU factorization with partial pivoting
+    template<class M, class PM>
+    typename M::size_type lu_factorize (M &m, PM &pm) {
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef M matrix_type;
+        matrix_type cm (m);
+#endif
+        size_type singular = 0;
+        size_type size1 = m.size1 ();
+        size_type size2 = m.size2 ();
+        size_type size = (std::min) (size1, size2);
+        for (size_type i = 0; i < size; ++ i) {
+            matrix_column<M> mci (column (m, i));
+            matrix_row<M> mri (row (m, i));
+            size_type i_norm_inf = i + index_norm_inf (project (mci, range (i, size1)));
+            BOOST_UBLAS_CHECK (i_norm_inf < size1, external_logic ());
+            if (m (i_norm_inf, i) != value_type/*zero*/()) {
+                if (i_norm_inf != i) {
+                    pm (i) = i_norm_inf;
+                    row (m, i_norm_inf).swap (mri);
+                } else {
+                    BOOST_UBLAS_CHECK (pm (i) == i_norm_inf, external_logic ());
+                }
+                value_type m_inv = value_type (1) / m (i, i);
+                project (mci, range (i + 1, size1)) *= m_inv;
+            } else if (singular == 0) {
+                singular = i + 1;
+            }
+            project (m, range (i + 1, size1), range (i + 1, size2)).minus_assign (
+                outer_prod (project (mci, range (i + 1, size1)),
+                            project (mri, range (i + 1, size2))));
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        swap_rows (pm, cm);
+        BOOST_UBLAS_CHECK (singular != 0 ||
+                           detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
+                                                                triangular_adaptor<matrix_type, upper> (m)), cm), internal_logic ());
+#endif
+        return singular;
+    }
+
+    template<class M, class PM>
+    typename M::size_type axpy_lu_factorize (M &m, PM &pm) {
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+        typedef vector<value_type> vector_type;
+
+#if BOOST_UBLAS_TYPE_CHECK
+        matrix_type cm (m);
+#endif
+        size_type singular = 0;
+        size_type size1 = m.size1 ();
+        size_type size2 = m.size2 ();
+        size_type size = (std::min) (size1, size2);
+#ifndef BOOST_UBLAS_LU_WITH_INPLACE_SOLVE
+        matrix_type mr (m);
+        mr.assign (zero_matrix<value_type> (size1, size2));
+        vector_type v (size1);
+        for (size_type i = 0; i < size; ++ i) {
+            matrix_range<matrix_type> lrr (project (mr, range (0, i), range (0, i)));
+            vector_range<matrix_column<matrix_type> > urr (project (column (mr, i), range (0, i)));
+            urr.assign (solve (lrr, project (column (m, i), range (0, i)), unit_lower_tag ()));
+            project (v, range (i, size1)).assign (
+                project (column (m, i), range (i, size1)) -
+                axpy_prod<vector_type> (project (mr, range (i, size1), range (0, i)), urr));
+            size_type i_norm_inf = i + index_norm_inf (project (v, range (i, size1)));
+            BOOST_UBLAS_CHECK (i_norm_inf < size1, external_logic ());
+            if (v (i_norm_inf) != value_type/*zero*/()) {
+                if (i_norm_inf != i) {
+                    pm (i) = i_norm_inf;
+                    std::swap (v (i_norm_inf), v (i));
+                    project (row (m, i_norm_inf), range (i + 1, size2)).swap (project (row (m, i), range (i + 1, size2)));
+                } else {
+                    BOOST_UBLAS_CHECK (pm (i) == i_norm_inf, external_logic ());
+                }
+                project (column (mr, i), range (i + 1, size1)).assign (
+                    project (v, range (i + 1, size1)) / v (i));
+                if (i_norm_inf != i) {
+                    project (row (mr, i_norm_inf), range (0, i)).swap (project (row (mr, i), range (0, i)));
+                }
+            } else if (singular == 0) {
+                singular = i + 1;
+            }
+            mr (i, i) = v (i);
+        }
+        m.assign (mr);
+#else
+        matrix_type lr (m);
+        matrix_type ur (m);
+        lr.assign (identity_matrix<value_type> (size1, size2));
+        ur.assign (zero_matrix<value_type> (size1, size2));
+        vector_type v (size1);
+        for (size_type i = 0; i < size; ++ i) {
+            matrix_range<matrix_type> lrr (project (lr, range (0, i), range (0, i)));
+            vector_range<matrix_column<matrix_type> > urr (project (column (ur, i), range (0, i)));
+            urr.assign (project (column (m, i), range (0, i)));
+            inplace_solve (lrr, urr, unit_lower_tag ());
+            project (v, range (i, size1)).assign (
+                project (column (m, i), range (i, size1)) -
+                axpy_prod<vector_type> (project (lr, range (i, size1), range (0, i)), urr));
+            size_type i_norm_inf = i + index_norm_inf (project (v, range (i, size1)));
+            BOOST_UBLAS_CHECK (i_norm_inf < size1, external_logic ());
+            if (v (i_norm_inf) != value_type/*zero*/()) {
+                if (i_norm_inf != i) {
+                    pm (i) = i_norm_inf;
+                    std::swap (v (i_norm_inf), v (i));
+                    project (row (m, i_norm_inf), range (i + 1, size2)).swap (project (row (m, i), range (i + 1, size2)));
+                } else {
+                    BOOST_UBLAS_CHECK (pm (i) == i_norm_inf, external_logic ());
+                }
+                project (column (lr, i), range (i + 1, size1)).assign (
+                    project (v, range (i + 1, size1)) / v (i));
+                if (i_norm_inf != i) {
+                    project (row (lr, i_norm_inf), range (0, i)).swap (project (row (lr, i), range (0, i)));
+                }
+            } else if (singular == 0) {
+                singular = i + 1;
+            }
+            ur (i, i) = v (i);
+        }
+        m.assign (triangular_adaptor<matrix_type, strict_lower> (lr) +
+                  triangular_adaptor<matrix_type, upper> (ur));
+#endif
+#if BOOST_UBLAS_TYPE_CHECK
+        swap_rows (pm, cm);
+        BOOST_UBLAS_CHECK (singular != 0 ||
+                           detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
+                                                                triangular_adaptor<matrix_type, upper> (m)), cm), internal_logic ());
+#endif
+        return singular;
+    }
+
+    // LU substitution
+    template<class M, class E>
+    void lu_substitute (const M &m, vector_expression<E> &e) {
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef const M const_matrix_type;
+        typedef vector<typename E::value_type> vector_type;
+
+        vector_type cv1 (e);
+#endif
+        inplace_solve (m, e, unit_lower_tag ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, unit_lower> (m), e), cv1), internal_logic ());
+        vector_type cv2 (e);
+#endif
+        inplace_solve (m, e, upper_tag ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, upper> (m), e), cv2), internal_logic ());
+#endif
+    }
+    template<class M, class E>
+    void lu_substitute (const M &m, matrix_expression<E> &e) {
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef const M const_matrix_type;
+        typedef matrix<typename E::value_type> matrix_type;
+
+        matrix_type cm1 (e);
+#endif
+        inplace_solve (m, e, unit_lower_tag ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, unit_lower> (m), e), cm1), internal_logic ());
+        matrix_type cm2 (e);
+#endif
+        inplace_solve (m, e, upper_tag ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, upper> (m), e), cm2), internal_logic ());
+#endif
+    }
+    template<class M, class PMT, class PMA, class MV>
+    void lu_substitute (const M &m, const permutation_matrix<PMT, PMA> &pm, MV &mv) {
+        swap_rows (pm, mv);
+        lu_substitute (m, mv);
+    }
+    template<class E, class M>
+    void lu_substitute (vector_expression<E> &e, const M &m) {
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef const M const_matrix_type;
+        typedef vector<typename E::value_type> vector_type;
+
+        vector_type cv1 (e);
+#endif
+        inplace_solve (e, m, upper_tag ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, upper> (m)), cv1), internal_logic ());
+        vector_type cv2 (e);
+#endif
+        inplace_solve (e, m, unit_lower_tag ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, unit_lower> (m)), cv2), internal_logic ());
+#endif
+    }
+    template<class E, class M>
+    void lu_substitute (matrix_expression<E> &e, const M &m) {
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef const M const_matrix_type;
+        typedef matrix<typename E::value_type> matrix_type;
+
+        matrix_type cm1 (e);
+#endif
+        inplace_solve (e, m, upper_tag ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, upper> (m)), cm1), internal_logic ());
+        matrix_type cm2 (e);
+#endif
+        inplace_solve (e, m, unit_lower_tag ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, unit_lower> (m)), cm2), internal_logic ());
+#endif
+    }
+    template<class MV, class M, class PMT, class PMA>
+    void lu_substitute (MV &mv, const M &m, const permutation_matrix<PMT, PMA> &pm) {
+        swap_rows (pm, mv);
+        lu_substitute (mv, m);
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/matrix.hpp b/include/boost/numeric/ublas/matrix.hpp
new file mode 100644
index 0000000..d063910
--- /dev/null
+++ b/include/boost/numeric/ublas/matrix.hpp
@@ -0,0 +1,5988 @@
+//
+//  Copyright (c) 2000-2010
+//  Joerg Walter, Mathias Koch, Gunter Winkler, David Bellot
+//  Copyright (c) 2014, Athanasios Iliopoulos
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_MATRIX_
+#define _BOOST_UBLAS_MATRIX_
+
+#include <boost/config.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix_expression.hpp>
+#include <boost/numeric/ublas/detail/matrix_assign.hpp>
+#include <boost/serialization/collection_size_type.hpp>
+#include <boost/serialization/array.hpp>
+#include <boost/serialization/nvp.hpp>
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { 
+	
+	/** \brief main namespace of uBLAS.
+	 *
+	 * Use this namespace for all operations with uBLAS. It can also be abbreviated with
+	 * \code namespace ublas = boost::numeric::ublas; \endcode
+	 *
+	 * A common practice is to bring this namespace into the current scope with
+	 * \code using namespace boost::numeric::ublas; \endcode.
+	 *
+	 * However, be warned that using the ublas namespace and the std::vector at the same time can lead to the compiler to confusion. 
+	 * The solution is simply to prefix each ublas vector like \c boost::numeric::ublas::vector<T>. If you think it's too long to 
+	 * write, you can define a new namespace like \c namespace ublas = boost::numeric::ublas and then just declare your vectors
+	 * with \c ublas::vector<T>. STL vectors will be declared as vector<T>. No need to prefix with \c std::
+	 */
+	namespace ublas {
+
+    namespace detail {
+        using namespace boost::numeric::ublas;
+
+        // Matrix resizing algorithm
+        template <class L, class M>
+        BOOST_UBLAS_INLINE
+        void matrix_resize_preserve (M& m, M& temporary) {
+            typedef L layout_type;
+            typedef typename M::size_type size_type;
+            const size_type msize1 (m.size1 ());        // original size
+            const size_type msize2 (m.size2 ());
+            const size_type size1 (temporary.size1 ());    // new size is specified by temporary
+            const size_type size2 (temporary.size2 ());
+            // Common elements to preserve
+            const size_type size1_min = (std::min) (size1, msize1);
+            const size_type size2_min = (std::min) (size2, msize2);
+            // Order for major and minor sizes
+            const size_type major_size = layout_type::size_M (size1_min, size2_min);
+            const size_type minor_size = layout_type::size_m (size1_min, size2_min);
+            // Indexing copy over major
+            for (size_type major = 0; major != major_size; ++major) {
+                for (size_type minor = 0; minor != minor_size; ++minor) {
+                        // find indexes - use invertability of element_ functions
+                    const size_type i1 = layout_type::index_M(major, minor);
+                    const size_type i2 = layout_type::index_m(major, minor);
+                    temporary.data () [layout_type::element (i1, size1, i2, size2)] =
+                            m.data() [layout_type::element (i1, msize1, i2, msize2)];
+                }
+            }
+            m.assign_temporary (temporary);
+        }
+    }
+
+    /** \brief A dense matrix of values of type \c T.
+     *
+     * For a \f$(m \times n)\f$-dimensional matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$ m_{i,j} \f$ is mapped to 
+     * the \f$(i.n + j)\f$-th element of the container for row major orientation or the \f$ (i + j.m) \f$-th element of 
+     * the container for column major orientation. In a dense matrix all elements are represented in memory in a 
+     * contiguous chunk of memory by definition.
+     * 
+     * Orientation and storage can also be specified, otherwise a \c row_major and \c unbounded_array are used. It is \b not 
+     * required by the storage to initialize elements of the matrix.
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+     * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
+     * \tparam A the type of Storage array. Default is \c unbounded_array
+     */
+    template<class T, class L, class A>
+    class matrix:
+        public matrix_container<matrix<T, L, A> > {
+
+        typedef T *pointer;
+        typedef L layout_type;
+        typedef matrix<T, L, A> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef A array_type;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef vector<T, A> vector_temporary_type;
+        typedef self_type matrix_temporary_type;
+        typedef dense_tag storage_category;
+        // This could be better for performance,
+        // typedef typename unknown_orientation_tag orientation_category;
+        // but others depend on the orientation information...
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+	  
+	  /// Default dense matrix constructor. Make a dense matrix of size (0,0)
+	    BOOST_UBLAS_INLINE
+	    matrix ():
+	        matrix_container<self_type> (),
+	        size1_ (0), size2_ (0), data_ () {}
+	
+	  /** Dense matrix constructor with defined size
+	   * \param size1 number of rows
+	   * \param size2 number of columns
+	   */
+	    BOOST_UBLAS_INLINE
+	    matrix (size_type size1, size_type size2):
+	        matrix_container<self_type> (),
+	        size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) {
+	    }
+	
+	  /** Dense matrix constructor with defined size a initial value for all the matrix elements
+	   * \param size1 number of rows
+	   * \param size2 number of columns
+	   * \param init initial value assigned to all elements
+	   */
+	    matrix (size_type size1, size_type size2, const value_type &init):
+	        matrix_container<self_type> (),
+	        size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2), init) {
+	    }
+
+	  /** Dense matrix constructor with defined size and an initial data array
+	   * \param size1 number of rows
+	   * \param size2 number of columns
+	   * \param data array to copy into the matrix. Must have the same dimension as the matrix
+	   */
+        BOOST_UBLAS_INLINE
+        matrix (size_type size1, size_type size2, const array_type &data):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), data_ (data) {}
+
+	  /** Copy-constructor of a dense matrix
+	   * \param m is a dense matrix
+	   */
+        BOOST_UBLAS_INLINE
+        matrix (const matrix &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
+
+	  /** Copy-constructor of a dense matrix from a matrix expression
+	   * \param ae is a matrix expression
+	   */
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix (const matrix_expression<AE> &ae):
+            matrix_container<self_type> (),
+            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::storage_size (size1_, size2_)) {
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+	  /** Return the number of rows of the matrix
+	   * You can also use the free size<>() function in operation/size.hpp as size<1>(m) where m is a matrix
+	   */
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+
+	  /** Return the number of colums of the matrix
+	   * You can also use the free size<>() function in operation/size.hpp as size<2>(m) where m is a matrix
+	   */
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+
+        // Storage accessors
+	  /** Return a constant reference to the internal storage of a dense matrix, i.e. the raw data
+	   * It's type depends on the type used by the matrix to store its data
+	   */
+        BOOST_UBLAS_INLINE
+        const array_type &data () const {
+            return data_;
+        }
+	  /** Return a reference to the internal storage of a dense matrix, i.e. the raw data
+	   * It's type depends on the type used by the matrix to store its data
+	   */
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+        // Resizing
+	  /** Resize a matrix to new dimensions
+	   * If data are preserved, then if the size if bigger at least on one dimension, extra values are filled with zeros.
+	   * If data are not preserved, then nothing has to be assumed regarding the content of the matrix after resizing.
+	   * \param size1 the new number of rows
+	   * \param size2 the new number of colums
+	   * \param preserve a boolean to say if one wants the data to be preserved during the resizing. Default is true.
+	   */
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            if (preserve) {
+                self_type temporary (size1, size2);
+                detail::matrix_resize_preserve<layout_type> (*this, temporary);
+            }
+            else {
+                data ().resize (layout_type::storage_size (size1, size2));
+                size1_ = size1;
+                size2_ = size2;
+            }
+        }
+
+        // Element access
+    
+    /** Access a matrix element. Here we return a const reference
+     * \param i the first coordinate of the element. By default it's the row
+     * \param j the second coordinate of the element. By default it's the column
+     * \return a const reference to the element
+     */
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return data () [layout_type::element (i, size1_, j, size2_)];
+        }
+
+    /** Access a matrix element. Here we return a reference
+     * \param i the first coordinate of the element. By default it's the row
+     * \param j the second coordinate of the element. By default it's the column
+     * \return a reference to the element
+     */
+        BOOST_UBLAS_INLINE
+        reference at_element (size_type i, size_type j) {
+            return data () [layout_type::element (i, size1_, j, size2_)];
+        }
+
+    /** Access a matrix element. Here we return a reference
+     * \param i the first coordinate of the element. By default it's the row
+     * \param j the second coordinate of the element. By default it's the column
+     * \return a reference to the element
+     */
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            return at_element (i, j);
+        }
+
+        // Element assignment
+
+    /** Change the value of a matrix element. Return back a reference to it
+     * \param i the first coordinate of the element. By default it's the row
+     * \param j the second coordinate of the element. By default it's the column
+     * \param t the new value of the element
+     * \return a reference to the newly changed element
+     */
+        BOOST_UBLAS_INLINE
+        reference insert_element (size_type i, size_type j, const_reference t) {
+            return (at_element (i, j) = t);
+        }
+
+    /** Erase the element 
+     * For most types (int, double, etc...) it means setting 0 (zero) the element at zero in fact.
+     * For user-defined types, it could be another value if you decided it. Your type in that case must
+     * contain a default null value.
+     * \param i the first coordinate of the element. By default it's the row
+     * \param j the second coordinate of the element. By default it's the column
+     */
+        void erase_element (size_type i, size_type j) {
+            at_element (i, j) = value_type/*zero*/();
+        }
+
+        // Zeroing
+    /** Erase all elements in the matrix
+     * For most types (int, double, etc...) it means writing 0 (zero) everywhere.
+     * For user-defined types, it could be another value if you decided it. Your type in that case must
+     * contain a default null value.
+     */
+        BOOST_UBLAS_INLINE
+        void clear () {
+            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
+        }
+
+        // Assignment
+#ifdef BOOST_UBLAS_MOVE_SEMANTICS
+
+        /*! @note "pass by value" the key idea to enable move semantics */
+        BOOST_UBLAS_INLINE
+        matrix &operator = (matrix m) {
+            assign_temporary(m);
+            return *this;
+        }
+#else
+        BOOST_UBLAS_INLINE
+        matrix &operator = (const matrix &m) {
+            size1_ = m.size1_;
+            size2_ = m.size2_;
+            data () = m.data ();
+            return *this;
+        }
+#endif
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        matrix &operator = (const matrix_container<C> &m) {
+            resize (m ().size1 (), m ().size2 (), false);
+            assign (m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        matrix &assign_temporary (matrix &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        matrix &operator += (const matrix_container<C> &m) {
+            plus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        matrix &operator -= (const matrix_container<C> &m) {
+            minus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (matrix &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                data ().swap (m.data ());
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (matrix &m1, matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use the storage array iterator
+        typedef typename A::const_iterator const_subiterator_type;
+        typedef typename A::iterator subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, i, j);
+#else
+            return const_iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int /* rank */, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator1 (*this, i, j);
+#else
+            return iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, i, j);
+#else
+            return const_iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int /* rank */, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator2 (*this, i, j);
+#else
+            return iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_));
+#endif
+        }
+
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename matrix::value_type value_type;
+            typedef typename matrix::difference_type difference_type;
+            typedef typename matrix::const_reference reference;
+            typedef const typename matrix::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                const self_type &m = (*this) ();
+                return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                const self_type &m = (*this) ();
+                return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+
+            friend class iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename matrix::value_type value_type;
+            typedef typename matrix::difference_type difference_type;
+            typedef typename matrix::reference reference;
+            typedef typename matrix::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, const subiterator_type &it):
+                container_reference<self_type> (m), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                self_type &m = (*this) ();
+                return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                self_type &m = (*this) ();
+                return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1_, 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename matrix::value_type value_type;
+            typedef typename matrix::difference_type difference_type;
+            typedef typename matrix::const_reference reference;
+            typedef const typename matrix::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                const self_type &m = (*this) ();
+                return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                const self_type &m = (*this) ();
+                return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+
+            friend class iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename matrix::value_type value_type;
+            typedef typename matrix::difference_type difference_type;
+            typedef typename matrix::reference reference;
+            typedef typename matrix::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, const subiterator_type &it):
+                container_reference<self_type> (m), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                self_type &m = (*this) ();
+                return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                self_type &m = (*this) ();
+                return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+        // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+        
+            // we need to copy to a collection_size_type to get a portable
+            // and efficient serialization
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+          
+            // serialize the sizes
+            ar & serialization::make_nvp("size1",s1)
+               & serialization::make_nvp("size2",s2);
+
+            // copy the values back if loading
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+            }
+            ar & serialization::make_nvp("data",data_);
+        }
+
+    private:
+        size_type size1_;
+        size_type size2_;
+        array_type data_;
+    };
+
+
+#ifdef BOOST_UBLAS_CPP_GE_2011
+    /** \brief A fixed size dense matrix of values of type \c T. Equivalent to a c-style 2 dimensional array.
+     *
+     * For a \f$(m \times n)\f$-dimensional fixed_matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$ m_{i,j} \f$ is mapped to
+     * the \f$(i.n + j)\f$-th element of the container for row major orientation or the \f$ (i + j.m) \f$-th element of
+     * the container for column major orientation. In a dense matrix all elements are represented in memory in a
+     * contiguous chunk of memory by definition.
+     *
+     * Orientation and storage can also be specified, otherwise \c row_major and \c std::array are used. It is \b not
+     * required by the storage container to initialize elements of the matrix.
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, std::complex<double>, etc...)
+     * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
+     * \tparam A the type of Storage array. Default is \c std::array<T, M*N>
+     */
+    template<class T, std::size_t M, std::size_t N, class L, class A>
+    class fixed_matrix:
+        public matrix_container<fixed_matrix<T, M, N, L, A> > {
+
+        typedef T *pointer;
+        typedef L layout_type;
+        typedef fixed_matrix<T, M, N, L, A> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef A array_type;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef vector<T, A> vector_temporary_type;
+        typedef self_type matrix_temporary_type;
+        typedef dense_tag storage_category;
+        // This could be better for performance,
+        // typedef typename unknown_orientation_tag orientation_category;
+        // but others depend on the orientation information...
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+
+      /// Default dense fixed_matrix constructor. Make a dense fixed_matrix of size M x N
+        BOOST_UBLAS_INLINE
+        fixed_matrix ():
+            matrix_container<self_type> (),
+            data_ () {}
+
+        /// \brief Construct a fixed_matrix from a list of values
+        /// The list may be included in curly braces. Typical syntax is choices are :
+        /// fixed_matrix<double, 2,2> v = { 1, 2, 3, 4 } or fixed_matrix<double,4> v( {1, 2, 3, 4} ) or fixed_matrix<double,2,2> v( 1, 2, 3, 4 )
+        template <typename... Types>
+        fixed_matrix(value_type v0, Types... vrest) :
+            matrix_container<self_type> (),
+            data_{ { v0, vrest... } } {}
+
+      /** Dense fixed_matrix constructor with defined initial value for all the matrix elements
+       * \param init initial value assigned to all elements
+       */
+        fixed_matrix (const value_type &init):
+            matrix_container<self_type> (),
+            data_ ( ) {
+            data_.fill(init);
+        }
+
+      /** Dense matrix constructor with defined initial data array
+       * \param data array to copy into the matrix. Must have the same dimension as the matrix
+       */
+        BOOST_UBLAS_INLINE
+        fixed_matrix (const array_type &data):
+            matrix_container<self_type> (),
+            data_ (data) {}
+
+      /** Copy-constructor of a dense fixed_matrix
+       * \param m is a dense fixed_matrix
+       */
+        BOOST_UBLAS_INLINE
+        fixed_matrix (const fixed_matrix &m):
+            matrix_container<self_type> (),
+            data_ (m.data_) {}
+
+      /** Copy-constructor of a dense matrix from a matrix expression
+       * \param ae is a matrix expression
+       */
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        fixed_matrix (const matrix_expression<AE> &ae):
+            matrix_container<self_type> (),
+            data_ () {
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+      /** Return the number of rows of the fixed_matrix
+       * You can also use the free size<>() function in operation/size.hpp as size<1>(m) where m is a fixed_matrix
+       */
+        BOOST_UBLAS_INLINE
+        BOOST_CONSTEXPR size_type size1 () const {
+            return M;
+        }
+
+      /** Return the number of colums of the fixed_matrix
+       * You can also use the free size<>() function in operation/size.hpp as size<2>(m) where m is a fixed_matrix
+       */
+        BOOST_UBLAS_INLINE
+        BOOST_CONSTEXPR size_type size2 () const {
+            return N;
+        }
+
+        // Storage accessors
+      /** Return a constant reference to the internal storage of a dense matrix, i.e. the raw data
+       * It's type depends on the type used by the matrix to store its data
+       */
+        BOOST_UBLAS_INLINE
+        const array_type &data () const {
+            return data_;
+        }
+      /** Return a reference to the internal storage of a dense fixed_matrix, i.e. the raw data
+       * It's type depends on the type used by the fixed_matrix to store its data
+       */
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+
+        // Element access
+
+    /** Access a fixed_matrix element. Here we return a const reference
+     * \param i the first coordinate of the element. By default it's the row
+     * \param j the second coordinate of the element. By default it's the column
+     * \return a const reference to the element
+     */
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return data () [layout_type::element (i, M, j, N)]; // Fixme: add static lookup for element(...) i.e.: element<M, N>(i,j)
+        }
+
+    /** Access a fixed_matrix element. Here we return a reference
+     * \param i the first coordinate of the element. By default it's the row
+     * \param j the second coordinate of the element. By default it's the column
+     * \return a reference to the element
+     */
+        BOOST_UBLAS_INLINE
+        reference at_element (size_type i, size_type j) {
+            return data () [layout_type::element (i, M, j, N)];
+        }
+
+    /** Access a fixed_matrix element. Here we return a reference
+     * \param i the first coordinate of the element. By default it's the row
+     * \param j the second coordinate of the element. By default it's the column
+     * \return a reference to the element
+     */
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            return at_element (i, j);
+        }
+
+        // Element assignment
+
+    /** Change the value of a fixed_matrix element. Return back a reference to it
+     * \param i the first coordinate of the element. By default it's the row
+     * \param j the second coordinate of the element. By default it's the column
+     * \param t the new value of the element
+     * \return a reference to the newly changed element
+     */
+        BOOST_UBLAS_INLINE
+        reference insert_element (size_type i, size_type j, const_reference t) {
+            return (at_element (i, j) = t);
+        }
+
+    /** Erase the element
+     * For most types (int, double, etc...) it means setting 0 (zero) the element at zero in fact.
+     * For user-defined types, it could be another value if you decided it. Your type in that case must
+     * contain a default null value.
+     * \param i the first coordinate of the element. By default it's the row
+     * \param j the second coordinate of the element. By default it's the column
+     */
+        void erase_element (size_type i, size_type j) {
+            at_element (i, j) = value_type/*zero*/();
+        }
+
+        // Zeroing
+    /** Erase all elements in the fixed_matrix
+     * For most types (int, double, etc...) it means writing 0 (zero) everywhere.
+     * For user-defined types, it could be another value if you decided it. Your type in that case must
+     * contain a default null value.
+     */
+        BOOST_UBLAS_INLINE
+        void clear () {
+            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
+        }
+
+        // Assignment
+#ifdef BOOST_UBLAS_MOVE_SEMANTICS
+
+        /*! @note "pass by value" the key idea to enable move semantics */
+        BOOST_UBLAS_INLINE
+        fixed_matrix &operator = (matrix m) {
+            assign_temporary(m);
+            return *this;
+        }
+#else
+        BOOST_UBLAS_INLINE
+        fixed_matrix &operator = (const fixed_matrix &m) {
+            data () = m.data ();
+            return *this;
+        }
+#endif
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        fixed_matrix &operator = (const matrix_container<C> &m) {
+            resize (m ().size1 (), m ().size2 (), false);
+            assign (m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        fixed_matrix &assign_temporary (fixed_matrix &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        fixed_matrix &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        fixed_matrix &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        fixed_matrix& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        fixed_matrix &operator += (const matrix_container<C> &m) {
+            plus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        fixed_matrix &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        fixed_matrix& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        fixed_matrix &operator -= (const matrix_container<C> &m) {
+            minus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        fixed_matrix &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        fixed_matrix& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        fixed_matrix& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (fixed_matrix &m) {
+            if (this != &m) {
+                data ().swap (m.data ());
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (fixed_matrix &m1, fixed_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use the storage array iterator
+        typedef typename A::const_iterator const_subiterator_type;
+        typedef typename A::iterator subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, i, j);
+#else
+            return const_iterator1 (*this, data ().begin () + layout_type::address (i, M, j, N));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int /* rank */, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator1 (*this, i, j);
+#else
+            return iterator1 (*this, data ().begin () + layout_type::address (i, M, j, N));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, i, j);
+#else
+            return const_iterator2 (*this, data ().begin () + layout_type::address (i, M, j, N));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int /* rank */, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator2 (*this, i, j);
+#else
+            return iterator2 (*this, data ().begin () + layout_type::address (i, M, j, N));
+#endif
+        }
+
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<fixed_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename fixed_matrix::value_type value_type;
+            typedef typename fixed_matrix::difference_type difference_type;
+            typedef typename fixed_matrix::const_reference reference;
+            typedef const typename fixed_matrix::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                const self_type &m = (*this) ();
+                return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                const self_type &m = (*this) ();
+                return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+
+            friend class iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, M, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<fixed_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename fixed_matrix::value_type value_type;
+            typedef typename fixed_matrix::difference_type difference_type;
+            typedef typename fixed_matrix::reference reference;
+            typedef typename fixed_matrix::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, const subiterator_type &it):
+                container_reference<self_type> (m), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                self_type &m = (*this) ();
+                return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                self_type &m = (*this) ();
+                return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, M, 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<fixed_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename fixed_matrix::value_type value_type;
+            typedef typename fixed_matrix::difference_type difference_type;
+            typedef typename fixed_matrix::const_reference reference;
+            typedef const typename fixed_matrix::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                const self_type &m = (*this) ();
+                return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                const self_type &m = (*this) ();
+                return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+
+            friend class iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, N);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<fixed_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename fixed_matrix::value_type value_type;
+            typedef typename fixed_matrix::difference_type difference_type;
+            typedef typename fixed_matrix::reference reference;
+            typedef typename fixed_matrix::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, const subiterator_type &it):
+                container_reference<self_type> (m), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ());
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                self_type &m = (*this) ();
+                return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                self_type &m = (*this) ();
+                return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, N);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+        // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+            ar & serialization::make_nvp("data",data_);
+        }
+
+    private:
+        array_type data_;
+    };
+
+#endif // BOOST_UBLAS_CPP_GE_2011
+
+    /** \brief A dense matrix of values of type \c T with a variable size bounded to a maximum of \f$M\f$ by \f$N\f$. 
+     *
+     * For a \f$(m \times n)\f$-dimensional matrix and \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$m_{i,j}\f$ is mapped
+     * to the \f$(i.n + j)\f$-th element of the container for row major orientation or the \f$(i + j.m)\f$-th element
+     * of the container for column major orientation. Finally in a dense matrix all elements are represented in memory 
+     * in a contiguous chunk of memory.
+     *
+     * Orientation can be specified. Default is \c row_major
+     * The default constructor creates the matrix with size \f$M\f$ by \f$N\f$. Elements are constructed by the storage 
+     * type \c bounded_array, which need not initialise their value.
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+     * \tparam M maximum and default number of rows (if not specified at construction)
+     * \tparam N maximum and default number of columns (if not specified at construction)
+     * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
+     */
+    template<class T, std::size_t M, std::size_t N, class L>
+    class bounded_matrix:
+        public matrix<T, L, bounded_array<T, M * N> > {
+
+        typedef matrix<T, L, bounded_array<T, M * N> > matrix_type;
+    public:
+        typedef typename matrix_type::size_type size_type;
+        static const size_type max_size1 = M;
+        static const size_type max_size2 = N;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        bounded_matrix ():
+            matrix_type (M, N) {}
+        BOOST_UBLAS_INLINE
+        bounded_matrix (size_type size1, size_type size2):
+            matrix_type (size1, size2) {}
+        BOOST_UBLAS_INLINE
+        bounded_matrix (const bounded_matrix &m):
+            matrix_type (m) {}
+        template<class A2>              // Allow matrix<T, L, bounded_array<M,N> > construction
+        BOOST_UBLAS_INLINE
+        bounded_matrix (const matrix<T, L, A2> &m):
+            matrix_type (m) {}
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        bounded_matrix (const matrix_expression<AE> &ae):
+            matrix_type (ae) {}
+        BOOST_UBLAS_INLINE
+        ~bounded_matrix () {}
+
+        // Assignment
+#ifdef BOOST_UBLAS_MOVE_SEMANTICS
+
+        /*! @note "pass by value" the key idea to enable move semantics */
+        BOOST_UBLAS_INLINE
+        bounded_matrix &operator = (bounded_matrix m) {
+            matrix_type::operator = (m);
+            return *this;
+        }
+#else
+        BOOST_UBLAS_INLINE
+        bounded_matrix &operator = (const bounded_matrix &m) {
+            matrix_type::operator = (m);
+            return *this;
+        }
+#endif
+        template<class L2, class A2>        // Generic matrix assignment
+        BOOST_UBLAS_INLINE
+        bounded_matrix &operator = (const matrix<T, L2, A2> &m) {
+            matrix_type::operator = (m);
+            return *this;
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        bounded_matrix &operator = (const matrix_container<C> &m) {
+            matrix_type::operator = (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        bounded_matrix &operator = (const matrix_expression<AE> &ae) {
+            matrix_type::operator = (ae);
+            return *this;
+        }
+    };
+
+
+    /** \brief A dense matrix of values of type \c T stored as a vector of vectors.
+    *
+    * Rows or columns are not stored into contiguous chunks of memory but data inside rows (or columns) are. 
+    * Orientation and storage can also be specified, otherwise a row major and unbounded arrays are used.
+    * The data is stored as a vector of vectors, meaning that rows or columns might not be stored into contiguous chunks
+    * of memory. Orientation and storage can also be specified, otherwise a row major and unbounded arrays are used. 
+    * The storage type defaults to \c unbounded_array<unbounded_array<T>> and orientation is \c row_major. It is \b not 
+    * required by the storage to initialize elements of the matrix. For a \f$(m \times n)\f$-dimensional matrix and 
+    * \f$ 0 \leq i < m, 0 \leq j < n\f$, every element \f$m_{i,j}\f$ is mapped to the \f$(i.n + j)\f$-th element of the 
+    * container for row major orientation or the \f$(i + j.m)\f$-th element of the container for column major orientation.
+    *
+    * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+    * \tparam L the storage organization. It can be either \c row_major or \c column_major. By default it is \c row_major
+    * \tparam A the type of Storage array. By default, it is an \unbounded_array<unbounder_array<T>>
+    */
+    template<class T, class L, class A>
+    class vector_of_vector:
+        public matrix_container<vector_of_vector<T, L, A> > {
+
+        typedef T *pointer;
+        typedef L layout_type;
+        typedef vector_of_vector<T, L, A> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef A array_type;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef vector<T, typename A::value_type> vector_temporary_type;
+        typedef self_type matrix_temporary_type;
+        typedef dense_tag storage_category;
+        // This could be better for performance,
+        // typedef typename unknown_orientation_tag orientation_category;
+        // but others depend on the orientation information...
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        vector_of_vector ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0), data_ (1) {}
+        BOOST_UBLAS_INLINE
+        vector_of_vector (size_type size1, size_type size2):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), data_ (1) {
+            resize (size1, size2, true);
+        }
+        BOOST_UBLAS_INLINE
+        vector_of_vector (const vector_of_vector &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_of_vector (const matrix_expression<AE> &ae):
+            matrix_container<self_type> (),
+            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size_M (size1_, size2_) + 1) {
+            for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k)
+                data ()[k].resize (layout_type::size_m (size1_, size2_));
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const { 
+            return size2_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const array_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            size1_ = size1;
+            size2_ = size2;
+            if (preserve)
+                data ().resize (layout_type::size_M (size1, size2) + 1, typename array_type::value_type ());
+            else
+                data ().resize (layout_type::size_M (size1, size2) + 1);
+            for (size_type k = 0; k < layout_type::size_M (size1, size2); ++ k) {
+                if (preserve)
+                    data () [k].resize (layout_type::size_m (size1, size2), value_type ());
+                else
+                    data () [k].resize (layout_type::size_m (size1, size2));
+            }
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)];
+        }
+        BOOST_UBLAS_INLINE
+        reference at_element (size_type i, size_type j) {
+            return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            return at_element (i, j); 
+        }
+
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        reference insert_element (size_type i, size_type j, const_reference t) {
+            return (at_element (i, j) = t); 
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i, size_type j) {
+            at_element (i, j) = value_type/*zero*/(); 
+        }
+        
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k)
+                std::fill (data () [k].begin (), data () [k].end (), value_type/*zero*/());
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        vector_of_vector &operator = (const vector_of_vector &m) {
+            size1_ = m.size1_;
+            size2_ = m.size2_;
+            data () = m.data ();
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        vector_of_vector &assign_temporary (vector_of_vector &m) { 
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_of_vector &operator = (const matrix_expression<AE> &ae) { 
+            self_type temporary (ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        vector_of_vector &operator = (const matrix_container<C> &m) {
+            resize (m ().size1 (), m ().size2 (), false);
+            assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_of_vector &assign (const matrix_expression<AE> &ae) { 
+            matrix_assign<scalar_assign> (*this, ae); 
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_of_vector& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        vector_of_vector &operator += (const matrix_container<C> &m) {
+            plus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_of_vector &plus_assign (const matrix_expression<AE> &ae) { 
+            matrix_assign<scalar_plus_assign> (*this, ae); 
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_of_vector& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        vector_of_vector &operator -= (const matrix_container<C> &m) {
+            minus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_of_vector &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae); 
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        vector_of_vector& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        vector_of_vector& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (vector_of_vector &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                data ().swap (m.data ());
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (vector_of_vector &m1, vector_of_vector &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use the vector iterator
+        typedef typename A::value_type::const_iterator const_subiterator_type;
+        typedef typename A::value_type::iterator subiterator_type;
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, i, j);
+#else
+            return const_iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin ()  + layout_type::index_m (i, j));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int /*rank*/, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator1 (*this, i, j);
+#else
+            return iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin ()  + layout_type::index_m (i, j));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, i, j);
+#else
+            return const_iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin ()  + layout_type::index_m (i, j));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int /*rank*/, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator2 (*this, i, j);
+#else
+            return iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j));
+#endif
+        }
+
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<vector_of_vector>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename vector_of_vector::value_type value_type;
+            typedef typename vector_of_vector::difference_type difference_type;
+            typedef typename vector_of_vector::const_reference reference;
+            typedef const typename vector_of_vector::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ i_;
+                const self_type &m = (*this) ();
+                if (layout_type::fast_i ())
+                    ++ it_;
+                else 
+                    it_ = m.find1 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- i_;
+                const self_type &m = (*this) ();
+                if (layout_type::fast_i ())
+                    -- it_;
+                else
+                    it_ = m.find1 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                i_ += n;
+                const self_type &m = (*this) ();
+                it_ = m.find1 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                i_ -= n;
+                const self_type &m = (*this) ();
+                it_ = m.find1 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
+                return index1 () - it.index1 ();
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return i_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return j_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
+                return it_ < it.it_;
+            }
+
+        private:
+            size_type i_;
+            size_type j_;
+            const_subiterator_type it_;
+
+            friend class iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<vector_of_vector>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename vector_of_vector::value_type value_type;
+            typedef typename vector_of_vector::difference_type difference_type;
+            typedef typename vector_of_vector::reference reference;
+            typedef typename vector_of_vector::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), i_ (), j_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it):
+                container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ i_;
+                self_type &m = (*this) ();
+                if (layout_type::fast_i ())
+                    ++ it_;
+                else
+                    it_ = m.find1 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- i_;
+                self_type &m = (*this) ();
+                if (layout_type::fast_i ())
+                    -- it_;
+                else
+                    it_ = m.find1 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                i_ += n;
+                self_type &m = (*this) ();
+                it_ = m.find1 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                i_ -= n;
+                self_type &m = (*this) ();
+                it_ = m.find1 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
+                return index1 () - it.index1 ();
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return i_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return j_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ());
+                return it_ < it.it_;
+            }
+
+        private:
+            size_type i_;
+            size_type j_;
+            subiterator_type it_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1_, 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<vector_of_vector>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename vector_of_vector::value_type value_type;
+            typedef typename vector_of_vector::difference_type difference_type;
+            typedef typename vector_of_vector::const_reference reference;
+            typedef const typename vector_of_vector::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), i_ (), j_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ j_;
+                const self_type &m = (*this) ();
+                if (layout_type::fast_j ())
+                    ++ it_;
+                else
+                    it_ = m.find2 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- j_;
+                const self_type &m = (*this) ();
+                if (layout_type::fast_j ())
+                    -- it_;
+                else
+                    it_ = m.find2 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                j_ += n;
+                const self_type &m = (*this) ();
+                it_ = m.find2 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                j_ -= n;
+                const self_type &m = (*this) ();
+                it_ = m.find2 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
+                return index2 () - it.index2 ();
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return i_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return j_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
+                return it_ < it.it_;
+            }
+
+        private:
+            size_type i_;
+            size_type j_;
+            const_subiterator_type it_;
+
+            friend class iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<vector_of_vector>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename vector_of_vector::value_type value_type;
+            typedef typename vector_of_vector::difference_type difference_type;
+            typedef typename vector_of_vector::reference reference;
+            typedef typename vector_of_vector::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), i_ (), j_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it):
+                container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ j_;
+                self_type &m = (*this) ();
+                if (layout_type::fast_j ())
+                    ++ it_;
+                else
+                    it_ = m.find2 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- j_;
+                self_type &m = (*this) ();
+                if (layout_type::fast_j ())
+                    -- it_;
+                else
+                    it_ = m.find2 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                j_ += n;
+                self_type &m = (*this) ();
+                it_ = m.find2 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                j_ -= n;
+                self_type &m = (*this) ();
+                it_ = m.find2 (1, i_, j_).it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
+                return index2 () - it.index2 ();
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return i_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return j_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ());
+                return it_ < it.it_;
+            }
+
+        private:
+            size_type i_;
+            size_type j_;
+            subiterator_type it_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+        // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+        
+            // we need to copy to a collection_size_type to get a portable
+            // and efficient serialization
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+          
+            // serialize the sizes
+            ar & serialization::make_nvp("size1",s1)
+               & serialization::make_nvp("size2",s2);
+
+            // copy the values back if loading
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+            }
+            ar & serialization::make_nvp("data",data_);
+        }
+
+    private:
+        size_type size1_;
+        size_type size2_;
+        array_type data_;
+    };
+
+
+    /** \brief A matrix with all values of type \c T equal to zero
+     *
+     * Changing values does not affect the matrix, however assigning it to a normal matrix will put zero 
+     * everywhere in the target matrix. All accesses are constant time, due to the trivial value.
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+     * \tparam ALLOC an allocator for storing the zero element. By default, a standar allocator is used.
+     */
+    template<class T, class ALLOC>
+    class zero_matrix:
+        public matrix_container<zero_matrix<T, ALLOC> > {
+
+        typedef const T *const_pointer;
+        typedef zero_matrix<T, ALLOC> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename ALLOC::size_type size_type;
+        typedef typename ALLOC::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef sparse_tag storage_category;
+        typedef unknown_orientation_tag orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        zero_matrix ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0) {}
+        BOOST_UBLAS_INLINE
+        zero_matrix (size_type size):
+            matrix_container<self_type> (),
+            size1_ (size), size2_ (size) {}
+        BOOST_UBLAS_INLINE
+        zero_matrix (size_type size1, size_type size2):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2) {}
+        BOOST_UBLAS_INLINE
+        zero_matrix (const zero_matrix &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, bool /*preserve*/ = true) {
+            size1_ = size;
+            size2_ = size;
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
+            size1_ = size1;
+            size2_ = size2;
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type /* i */, size_type /* j */) const {
+            return zero_;
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        zero_matrix &operator = (const zero_matrix &m) {
+            size1_ = m.size1_;
+            size2_ = m.size2_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        zero_matrix &assign_temporary (zero_matrix &m) {
+            swap (m);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (zero_matrix &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (zero_matrix &m1, zero_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    public:
+        class const_iterator1;
+        class const_iterator2;
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
+            return const_iterator1 (*this);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /*rank*/, size_type /*i*/, size_type /*j*/) const {
+            return const_iterator2 (*this);
+        }
+
+        class const_iterator1:
+            public container_const_reference<zero_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename zero_matrix::value_type value_type;
+            typedef typename zero_matrix::difference_type difference_type;
+            typedef typename zero_matrix::const_reference reference;
+            typedef typename zero_matrix::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m):
+                container_const_reference<self_type> (m) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                BOOST_UBLAS_CHECK_FALSE (bad_index ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                BOOST_UBLAS_CHECK_FALSE (bad_index ());
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK_FALSE (bad_index ());
+                return zero_;   // arbitary return value
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return const_iterator2 ((*this) ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return const_iterator2 ((*this) ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK_FALSE (bad_index ());
+                return 0;   // arbitary return value
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK_FALSE (bad_index ());
+                return 0;   // arbitary return value
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                detail::ignore_unused_variable_warning(it);
+                return true;
+            }
+        };
+
+        typedef const_iterator1 iterator1;
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return const_iterator1 (*this);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return const_iterator1 (*this);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+        class const_iterator2:
+            public container_const_reference<zero_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename zero_matrix::value_type value_type;
+            typedef typename zero_matrix::difference_type difference_type;
+            typedef typename zero_matrix::const_reference reference;
+            typedef typename zero_matrix::const_pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m):
+                container_const_reference<self_type> (m) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                BOOST_UBLAS_CHECK_FALSE (bad_index ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                BOOST_UBLAS_CHECK_FALSE (bad_index ());
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK_FALSE (bad_index ());
+                return zero_;   // arbitary return value
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return const_iterator1 ((*this) ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return const_iterator1 ((*this) ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK_FALSE (bad_index ());
+                return 0;   // arbitary return value
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK_FALSE (bad_index ());
+                return 0;   // arbitary return value
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                detail::ignore_unused_variable_warning(it);
+                return true;
+            }
+        };
+
+        typedef const_iterator2 iterator2;
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+        
+            // we need to copy to a collection_size_type to get a portable
+            // and efficient serialization
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+          
+            // serialize the sizes
+            ar & serialization::make_nvp("size1",s1)
+               & serialization::make_nvp("size2",s2);
+
+            // copy the values back if loading
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+            }
+        }
+
+    private:
+        size_type size1_;
+        size_type size2_;
+        static const value_type zero_;
+    };
+
+    template<class T, class ALLOC>
+    const typename zero_matrix<T, ALLOC>::value_type zero_matrix<T, ALLOC>::zero_ = T(/*zero*/);
+
+    /** \brief An identity matrix with values of type \c T
+     *
+     * Elements or cordinates \f$(i,i)\f$ are equal to 1 (one) and all others to 0 (zero). 
+     * Changing values does not affect the matrix, however assigning it to a normal matrix will
+     * make the matrix equal to an identity matrix. All accesses are constant du to the trivial values.
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+     * \tparam ALLOC an allocator for storing the zeros and one elements. By default, a standar allocator is used.
+     */ 
+    template<class T, class ALLOC>
+    class identity_matrix:
+        public matrix_container<identity_matrix<T, ALLOC> > {
+
+        typedef const T *const_pointer;
+        typedef identity_matrix<T, ALLOC> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename ALLOC::size_type size_type;
+        typedef typename ALLOC::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef sparse_tag storage_category;
+        typedef unknown_orientation_tag orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        identity_matrix ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0), size_common_ (0) {}
+        BOOST_UBLAS_INLINE
+        identity_matrix (size_type size):
+            matrix_container<self_type> (),
+            size1_ (size), size2_ (size), size_common_ ((std::min) (size1_, size2_)) {}
+        BOOST_UBLAS_INLINE
+        identity_matrix (size_type size1, size_type size2):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), size_common_ ((std::min) (size1_, size2_)) {}
+        BOOST_UBLAS_INLINE
+        identity_matrix (const identity_matrix &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_), size_common_ ((std::min) (size1_, size2_)) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, bool /*preserve*/ = true) {
+            size1_ = size;
+            size2_ = size;
+            size_common_ = ((std::min)(size1_, size2_));
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
+            size1_ = size1;
+            size2_ = size2;
+            size_common_ = ((std::min)(size1_, size2_));
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            if (i == j)
+                return one_;
+            else
+                return zero_;
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        identity_matrix &operator = (const identity_matrix &m) {
+            size1_ = m.size1_;
+            size2_ = m.size2_;
+            size_common_ = m.size_common_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        identity_matrix &assign_temporary (identity_matrix &m) { 
+            swap (m);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (identity_matrix &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                std::swap (size_common_, m.size_common_);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (identity_matrix &m1, identity_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use an index
+        typedef size_type const_subiterator_type;
+
+    public:
+        class const_iterator1;
+        class const_iterator2;
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            if (rank == 1) {
+                i = (std::max) (i, j);
+                i = (std::min) (i, j + 1);
+            }
+            return const_iterator1 (*this, i);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            if (rank == 1) {
+                j = (std::max) (j, i);
+                j = (std::min) (j, i + 1);
+            }
+            return const_iterator2 (*this, j);
+        }
+
+
+        class const_iterator1:
+            public container_const_reference<identity_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename identity_matrix::value_type value_type;
+            typedef typename identity_matrix::difference_type difference_type;
+            typedef typename identity_matrix::const_reference reference;
+            typedef typename identity_matrix::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                BOOST_UBLAS_CHECK (it_ < (*this) ().size1 (), bad_index ());
+                ++it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
+                --it_;
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return one_;
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return const_iterator2 ((*this) (), it_); 
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return const_iterator2 ((*this) (), it_ + 1); 
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+
+        typedef const_iterator1 iterator1;
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return const_iterator1 (*this, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return const_iterator1 (*this, size_common_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+        class const_iterator2:
+            public container_const_reference<identity_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename identity_matrix::value_type value_type;
+            typedef typename identity_matrix::difference_type difference_type;
+            typedef typename identity_matrix::const_reference reference;
+            typedef typename identity_matrix::const_pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                BOOST_UBLAS_CHECK (it_ < (*this) ().size_common_, bad_index ());
+                ++it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
+                --it_;
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return one_;
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return const_iterator1 ((*this) (), it_); 
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return const_iterator1 ((*this) (), it_ + 1); 
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+
+        typedef const_iterator2 iterator2;
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return const_iterator2 (*this, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return const_iterator2 (*this, size_common_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+        
+            // we need to copy to a collection_size_type to get a portable
+            // and efficient serialization
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+          
+            // serialize the sizes
+            ar & serialization::make_nvp("size1",s1)
+               & serialization::make_nvp("size2",s2);
+
+            // copy the values back if loading
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+                size_common_ = ((std::min)(size1_, size2_));
+            }
+        }
+
+    private:
+        size_type size1_;
+        size_type size2_;
+        size_type size_common_;
+        static const value_type zero_;
+        static const value_type one_;
+    };
+
+    template<class T, class ALLOC>
+    const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::zero_ = T(/*zero*/);
+    template<class T, class ALLOC>
+    const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here
+
+
+    /** \brief A matrix with all values of type \c T equal to the same value
+     *
+     * Changing one value has the effect of changing all the values. Assigning it to a normal matrix will copy
+     * the same value everywhere in this matrix. All accesses are constant time, due to the trivial value.
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+     * \tparam ALLOC an allocator for storing the unique value. By default, a standar allocator is used.
+     */
+    template<class T, class ALLOC>
+    class scalar_matrix:
+        public matrix_container<scalar_matrix<T, ALLOC> > {
+
+        typedef const T *const_pointer;
+        typedef scalar_matrix<T, ALLOC> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef std::size_t size_type;
+        typedef std::ptrdiff_t difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef dense_tag storage_category;
+        typedef unknown_orientation_tag orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        scalar_matrix ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0), value_ () {}
+        BOOST_UBLAS_INLINE
+        scalar_matrix (size_type size1, size_type size2, const value_type &value = value_type(1)):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), value_ (value) {}
+        BOOST_UBLAS_INLINE
+        scalar_matrix (const scalar_matrix &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_), value_ (m.value_) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool /*preserve*/ = true) {
+            size1_ = size1;
+            size2_ = size2;
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type /*i*/, size_type /*j*/) const {
+            return value_; 
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        scalar_matrix &operator = (const scalar_matrix &m) {
+            size1_ = m.size1_;
+            size2_ = m.size2_;
+            value_ = m.value_;
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        scalar_matrix &assign_temporary (scalar_matrix &m) { 
+            swap (m);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (scalar_matrix &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                std::swap (value_, m.value_);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (scalar_matrix &m1, scalar_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use an index
+        typedef size_type const_subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
+        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class const_iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
+            return const_iterator1 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
+            return const_iterator2 (*this, i, j);
+        }   
+
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<scalar_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename scalar_matrix::value_type value_type;
+            typedef typename scalar_matrix::difference_type difference_type;
+            typedef typename scalar_matrix::const_reference reference;
+            typedef typename scalar_matrix::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
+                container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return (*this) () (index1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const scalar_matrix &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const scalar_matrix &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<scalar_matrix>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            const_subiterator_type it1_;
+            const_subiterator_type it2_;
+        };
+
+        typedef const_iterator1 iterator1;
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<scalar_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename scalar_matrix::value_type value_type;
+            typedef typename scalar_matrix::difference_type difference_type;
+            typedef typename scalar_matrix::const_reference reference;
+            typedef typename scalar_matrix::const_pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<scalar_matrix> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2):
+                container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return (*this) () (index1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const scalar_matrix &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const scalar_matrix &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<scalar_matrix>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator_type it1_;
+            const_subiterator_type it2_;
+        };
+
+        typedef const_iterator2 iterator2;
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+        
+            // we need to copy to a collection_size_type to get a portable
+            // and efficient serialization
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+          
+            // serialize the sizes
+            ar & serialization::make_nvp("size1",s1)
+               & serialization::make_nvp("size2",s2);
+
+            // copy the values back if loading
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+            }
+
+            ar & serialization::make_nvp("value", value_);
+        }
+
+    private:
+        size_type size1_;
+        size_type size2_;
+        value_type value_;
+    };
+
+
+    /** \brief An array based matrix class which size is defined at type specification or object instanciation
+     *
+     * This matrix is directly based on a predefined C-style arry of data, thus providing the fastest
+     * implementation possible. The constraint is that dimensions of the matrix must be specified at 
+     * the instanciation or the type specification. 
+     *
+     * For instance, \code typedef c_matrix<double,4,4> my_4by4_matrix \endcode 
+     * defines a 4 by 4 double-precision matrix.  You can also instantiate it directly with 
+     * \code c_matrix<int,8,5> my_fast_matrix \endcode. This will make a 8 by 5 integer matrix. The 
+     * price to pay for this speed is that you cannot resize it to a size larger than the one defined 
+     * in the template parameters. In the previous example, a size of 4 by 5 or 3 by 2 is acceptable, 
+     * but a new size of 9 by 5 or even 10 by 10 will raise a bad_size() exception.
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+     * \tparam N the default maximum number of rows
+     * \tparam M the default maximum number of columns
+     */
+    template<class T, std::size_t N, std::size_t M>
+    class c_matrix:
+        public matrix_container<c_matrix<T, N, M> > {
+
+        typedef c_matrix<T, N, M> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef std::size_t size_type;
+        typedef std::ptrdiff_t difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef const T *const_pointer;
+        typedef T *pointer;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef c_vector<T, N * M> vector_temporary_type;     // vector able to store all elements of c_matrix
+        typedef self_type matrix_temporary_type;
+        typedef dense_tag storage_category;
+        // This could be better for performance,
+        // typedef typename unknown_orientation_tag orientation_category;
+        // but others depend on the orientation information...
+        typedef row_major_tag orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        c_matrix ():
+            size1_ (N), size2_ (M) /* , data_ () */ {
+        }
+        BOOST_UBLAS_INLINE
+        c_matrix (size_type size1, size_type size2):
+            size1_ (size1), size2_ (size2) /* , data_ () */ {
+            if (size1_ > N || size2_ > M)
+                bad_size ().raise ();
+        }
+        BOOST_UBLAS_INLINE
+        c_matrix (const c_matrix &m):
+            size1_ (m.size1_), size2_ (m.size2_) /* , data_ () */ {
+            if (size1_ > N || size2_ > M)
+                bad_size ().raise ();
+            assign(m);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        c_matrix (const matrix_expression<AE> &ae):
+            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()) /* , data_ () */ {
+            if (size1_ > N || size2_ > M)
+                bad_size ().raise ();
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+        BOOST_UBLAS_INLINE
+        const_pointer data () const {
+            return reinterpret_cast<const_pointer> (data_);
+        }
+        BOOST_UBLAS_INLINE
+        pointer data () {
+            return reinterpret_cast<pointer> (data_);
+        }
+
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            if (size1 > N || size2 > M)
+                bad_size ().raise ();
+            if (preserve) {
+                self_type temporary (size1, size2);
+                // Common elements to preserve
+                const size_type size1_min = (std::min) (size1, size1_);
+                const size_type size2_min = (std::min) (size2, size2_);
+                for (size_type i = 0; i != size1_min; ++i) {    // indexing copy over major
+                    for (size_type j = 0; j != size2_min; ++j) {
+                        temporary.data_[i][j] = data_[i][j];
+                    }
+                }
+                assign_temporary (temporary);
+            }
+            else {
+                size1_ = size1;
+                size2_ = size2;
+            }
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
+            return data_ [i] [j];
+        }
+        BOOST_UBLAS_INLINE
+        reference at_element (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
+            return data_ [i] [j];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            return at_element (i, j);
+        }
+
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        reference insert_element (size_type i, size_type j, const_reference t) {
+            return (at_element (i, j) = t);
+        }
+        
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            for (size_type i = 0; i < size1_; ++ i)
+                std::fill (data_ [i], data_ [i] + size2_, value_type/*zero*/());
+        }
+
+        // Assignment
+#ifdef BOOST_UBLAS_MOVE_SEMANTICS
+
+        /*! @note "pass by value" the key idea to enable move semantics */
+        BOOST_UBLAS_INLINE
+        c_matrix &operator = (c_matrix m) {
+            assign_temporary(m);
+            return *this;
+        }
+#else
+        BOOST_UBLAS_INLINE
+        c_matrix &operator = (const c_matrix &m) {
+            size1_ = m.size1_;
+            size2_ = m.size2_;
+            for (size_type i = 0; i < m.size1_; ++ i)
+                std::copy (m.data_ [i], m.data_ [i] + m.size2_, data_ [i]);
+            return *this;
+        }
+#endif
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        c_matrix &operator = (const matrix_container<C> &m) {
+            resize (m ().size1 (), m ().size2 (), false);
+            assign (m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        c_matrix &assign_temporary (c_matrix &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        c_matrix &operator = (const matrix_expression<AE> &ae) { 
+            self_type temporary (ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        c_matrix &assign (const matrix_expression<AE> &ae) { 
+            matrix_assign<scalar_assign> (*this, ae); 
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        c_matrix& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        c_matrix &operator += (const matrix_container<C> &m) {
+            plus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        c_matrix &plus_assign (const matrix_expression<AE> &ae) { 
+            matrix_assign<scalar_plus_assign> (*this, ae); 
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        c_matrix& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        c_matrix &operator -= (const matrix_container<C> &m) {
+            minus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        c_matrix &minus_assign (const matrix_expression<AE> &ae) { 
+            matrix_assign<scalar_minus_assign> (*this, ae); 
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        c_matrix& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        c_matrix& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (c_matrix &m) {
+            if (this != &m) {
+                BOOST_UBLAS_CHECK (size1_ == m.size1_, bad_size ());
+                BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ());
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                for (size_type i = 0; i < size1_; ++ i)
+                    std::swap_ranges (data_ [i], data_ [i] + size2_, m.data_ [i]);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (c_matrix &m1, c_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use pointers for iterator
+        typedef const_pointer const_subiterator_type;
+        typedef pointer subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, i, j);
+#else
+            return const_iterator1 (*this, &data_ [i] [j]);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int /*rank*/, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator1 (*this, i, j);
+#else
+            return iterator1 (*this, &data_ [i] [j]);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, i, j);
+#else
+            return const_iterator2 (*this, &data_ [i] [j]);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int /*rank*/, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator2 (*this, i, j);
+#else
+            return iterator2 (*this, &data_ [i] [j]);
+#endif
+        }
+
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<c_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename c_matrix::difference_type difference_type;
+            typedef typename c_matrix::value_type value_type;
+            typedef typename c_matrix::const_reference reference;
+            typedef typename c_matrix::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                it_ += M;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                it_ -= M;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it_ += n * M;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it_ -= n * M;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return (it_ - it.it_) / M;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                const self_type &m = (*this) ();
+                return (it_ - m.begin1 ().it_) / M;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                const self_type &m = (*this) ();
+                return (it_ - m.begin1 ().it_) % M;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+
+            friend class iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<c_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+
+            typedef typename c_matrix::difference_type difference_type;
+            typedef typename c_matrix::value_type value_type;
+            typedef typename c_matrix::reference reference;
+            typedef typename c_matrix::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, const subiterator_type &it):
+                container_reference<self_type> (m), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                it_ += M;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                it_ -= M;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it_ += n * M;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it_ -= n * M;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return (it_ - it.it_) / M;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                const self_type &m = (*this) ();
+                return (it_ - m.begin1 ().it_) / M;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                const self_type &m = (*this) ();
+                return (it_ - m.begin1 ().it_) % M;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1_, 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<c_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename c_matrix::difference_type difference_type;
+            typedef typename c_matrix::value_type value_type;
+            typedef typename c_matrix::const_reference reference;
+            typedef typename c_matrix::const_reference pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                const self_type &m = (*this) ();
+                return (it_ - m.begin2 ().it_) / M;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                const self_type &m = (*this) ();
+                return (it_ - m.begin2 ().it_) % M;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+
+            friend class iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<c_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename c_matrix::difference_type difference_type;
+            typedef typename c_matrix::value_type value_type;
+            typedef typename c_matrix::reference reference;
+            typedef typename c_matrix::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, const subiterator_type &it):
+                container_reference<self_type> (m), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                const self_type &m = (*this) ();
+                return (it_ - m.begin2 ().it_) / M;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                const self_type &m = (*this) ();
+                return (it_ - m.begin2 ().it_) % M;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+        
+            // we need to copy to a collection_size_type to get a portable
+            // and efficient serialization
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+          
+            // serialize the sizes
+            ar & serialization::make_nvp("size1",s1)
+               & serialization::make_nvp("size2",s2);
+
+            // copy the values back if loading
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+            }
+            // could probably use make_array( &(data[0][0]), N*M ) 
+            ar & serialization::make_array(data_, N);
+        }
+
+    private:
+        size_type size1_;
+        size_type size2_;
+        value_type data_ [N] [M];
+    };
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/matrix_expression.hpp b/include/boost/numeric/ublas/matrix_expression.hpp
new file mode 100644
index 0000000..a363130
--- /dev/null
+++ b/include/boost/numeric/ublas/matrix_expression.hpp
@@ -0,0 +1,5633 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_MATRIX_EXPRESSION_
+#define _BOOST_UBLAS_MATRIX_EXPRESSION_
+
+#include <boost/numeric/ublas/vector_expression.hpp>
+
+// Expression templates based on ideas of Todd Veldhuizen and Geoffrey Furnish
+// Iterators based on ideas of Jeremy Siek
+//
+// Classes that model the Matrix Expression concept
+
+namespace boost { namespace numeric { namespace ublas {
+
+    template<class E>
+    class matrix_reference:
+        public matrix_expression<matrix_reference<E> > {
+
+        typedef matrix_reference<E> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef typename E::size_type size_type;
+        typedef typename E::difference_type difference_type;
+        typedef typename E::value_type value_type;
+        typedef typename E::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<E>,
+                                          typename E::const_reference,
+                                          typename E::reference>::type reference;
+        typedef E referred_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename E::orientation_category orientation_category;
+        typedef typename E::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        explicit matrix_reference (referred_type &e):
+              e_ (e) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return e_.size1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return e_.size2 ();
+        }
+
+    public:
+        // Expression accessors - const correct
+        BOOST_UBLAS_INLINE
+        const referred_type &expression () const {
+            return e_;
+        }
+        BOOST_UBLAS_INLINE
+        referred_type &expression () {
+            return e_;
+        }
+
+    public:
+        // Element access
+#ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return expression () (i, j);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            return expression () (i, j);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) const {
+            return expression () (i, j);
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        matrix_reference &operator = (const matrix_reference &m) {
+            expression ().operator = (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_reference &operator = (const matrix_expression<AE> &ae) {
+            expression ().operator = (ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_reference &assign (const matrix_expression<AE> &ae) {
+            expression ().assign (ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_reference &operator += (const matrix_expression<AE> &ae) {
+            expression ().operator += (ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_reference &plus_assign (const matrix_expression<AE> &ae) {
+            expression ().plus_assign (ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_reference &operator -= (const matrix_expression<AE> &ae) {
+            expression ().operator -= (ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_reference &minus_assign (const matrix_expression<AE> &ae) {
+            expression ().minus_assign (ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_reference &operator *= (const AT &at) {
+            expression ().operator *= (at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_reference &operator /= (const AT &at) {
+            expression ().operator /= (at);
+            return *this;
+        }
+
+         // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (matrix_reference &m) {
+            expression ().swap (m.expression ());
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_reference &mr) const {
+            return &(*this).e_ == &mr.e_;
+        }
+
+        // Iterator types
+        typedef typename E::const_iterator1 const_iterator1;
+        typedef typename boost::mpl::if_<boost::is_const<E>,
+                                          typename E::const_iterator1,
+                                          typename E::iterator1>::type iterator1;
+        typedef typename E::const_iterator2 const_iterator2;
+        typedef typename boost::mpl::if_<boost::is_const<E>,
+                                          typename E::const_iterator2,
+                                          typename E::iterator2>::type iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            return expression ().find1 (rank, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int rank, size_type i, size_type j) {
+            return expression ().find1 (rank, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            return expression ().find2 (rank, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int rank, size_type i, size_type j) {
+            return expression ().find2 (rank, i, j);
+        }
+
+        // Iterators are the iterators of the referenced expression.
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return expression ().begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return expression ().end1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return expression ().begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return expression ().end1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return expression ().begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return expression ().end2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return expression ().begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return expression ().end2 ();
+        }
+
+        // Reverse iterators
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        referred_type &e_;
+    };
+
+
+    template<class E1, class E2, class F>
+    class vector_matrix_binary:
+        public matrix_expression<vector_matrix_binary<E1, E2, F> > {
+
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+    public:
+        typedef typename E1::const_closure_type expression1_closure_type;
+        typedef typename E2::const_closure_type expression2_closure_type;
+    private:
+        typedef vector_matrix_binary<E1, E2, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef F functor_type;
+        typedef typename promote_traits<typename E1::size_type, typename E2::size_type>::promote_type size_type;
+        typedef typename promote_traits<typename E1::difference_type, typename E2::difference_type>::promote_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef unknown_orientation_tag orientation_category;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction 
+        BOOST_UBLAS_INLINE
+        vector_matrix_binary (const expression1_type &e1, const expression2_type &e2): 
+            e1_ (e1), e2_ (e2) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return e1_.size ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const { 
+            return e2_.size ();
+        }
+
+    public:
+        // Expression accessors
+        BOOST_UBLAS_INLINE
+        const expression1_closure_type &expression1 () const {
+            return e1_;
+        }
+        BOOST_UBLAS_INLINE
+        const expression2_closure_type &expression2 () const {
+            return e2_;
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return functor_type::apply (e1_ (i), e2_ (j));
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const vector_matrix_binary &vmb) const {
+            return (*this).expression1 ().same_closure (vmb.expression1 ()) &&
+                   (*this).expression2 ().same_closure (vmb.expression2 ());
+        }
+
+        // Iterator types
+    private:
+        typedef typename E1::const_iterator const_subiterator1_type;
+        typedef typename E2::const_iterator const_subiterator2_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef typename iterator_restrict_traits<typename const_subiterator1_type::iterator_category,
+                                                  typename const_subiterator2_type::iterator_category>::iterator_category iterator_category;
+        typedef indexed_const_iterator1<const_closure_type, iterator_category> const_iterator1;
+        typedef const_iterator1 iterator1;
+        typedef indexed_const_iterator2<const_closure_type, iterator_category> const_iterator2;
+        typedef const_iterator2 iterator2;
+#else
+        class const_iterator1;
+        typedef const_iterator1 iterator1;
+        class const_iterator2;
+        typedef const_iterator2 iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            const_subiterator1_type it1 (e1_.find (i));
+            const_subiterator1_type it1_end (e1_.find (size1 ()));
+            const_subiterator2_type it2 (e2_.find (j));
+            const_subiterator2_type it2_end (e2_.find (size2 ()));
+            if (it2 == it2_end || (rank == 1 && (it2.index () != j || *it2 == value_type/*zero*/()))) {
+                it1 = it1_end;
+                it2 = it2_end;
+            }
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, it1.index (), it2.index ());
+#else
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            return const_iterator1 (*this, it1, it2, it2 != it2_end ? *it2 : value_type/*zero*/());
+#else
+            return const_iterator1 (*this, it1, it2);
+#endif
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            const_subiterator2_type it2 (e2_.find (j));
+            const_subiterator2_type it2_end (e2_.find (size2 ()));
+            const_subiterator1_type it1 (e1_.find (i));
+            const_subiterator1_type it1_end (e1_.find (size1 ()));
+            if (it1 == it1_end || (rank == 1 && (it1.index () != i || *it1 == value_type/*zero*/()))) {
+                it2 = it2_end;
+                it1 = it1_end;
+            }
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, it1.index (), it2.index ());
+#else
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            return const_iterator2 (*this, it1, it2, it1 != it1_end ? *it1 : value_type/*zero*/());
+#else
+            return const_iterator2 (*this, it1, it2);
+#endif
+#endif
+        }
+
+        // Iterators enhance the iterators of the referenced expressions
+        // with the binary functor.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<vector_matrix_binary>,
+            public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
+                                                                          typename E2::const_iterator::iterator_category>::iterator_category>::template
+                iterator_base<const_iterator1, value_type>::type {
+        public:
+            typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
+                                                      typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
+            typedef typename vector_matrix_binary::difference_type difference_type;
+            typedef typename vector_matrix_binary::value_type value_type;
+            typedef typename vector_matrix_binary::const_reference reference;
+            typedef typename vector_matrix_binary::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ (), t2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2, value_type t2):
+                container_const_reference<self_type> (vmb), it1_ (it1), it2_ (it2), t2_ (t2) {}
+#else
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (vmb), it1_ (it1), it2_ (it2) {}
+#endif
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (*it1_, t2_);
+#else
+                return functor_type::apply (*it1_, *it2_);
+#endif
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type  index2 () const {
+                return it2_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                t2_ = it.t2_;
+#endif
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            const_subiterator1_type it1_;
+            // Mutable due to assignment
+            /* const */ const_subiterator2_type it2_;
+            value_type t2_;
+#else
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+#endif
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<vector_matrix_binary>,
+            public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
+                                                                          typename E2::const_iterator::iterator_category>::iterator_category>::template
+                iterator_base<const_iterator2, value_type>::type {
+        public:
+            typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category, 
+                                                      typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
+            typedef typename vector_matrix_binary::difference_type difference_type;
+            typedef typename vector_matrix_binary::value_type value_type;
+            typedef typename vector_matrix_binary::const_reference reference;
+            typedef typename vector_matrix_binary::const_pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ (), t1_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2, value_type t1):
+                container_const_reference<self_type> (vmb), it1_ (it1), it2_ (it2), t1_ (t1) {}
+#else
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (vmb), it1_ (it1), it2_ (it2) {}
+#endif
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure(it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (t1_, *it2_);
+#else
+                return functor_type::apply (*it1_, *it2_);
+#endif
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type  index2 () const {
+                return it2_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                t1_ = it.t1_;
+#endif
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure( it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            // Mutable due to assignment
+            /* const */ const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+            value_type t1_;
+#else
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+#endif
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class E1, class E2, class F>
+    struct vector_matrix_binary_traits {
+        typedef vector_matrix_binary<E1, E2, F> expression_type;
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type; 
+#else
+        // ISSUE matrix is arbitary temporary type
+        typedef matrix<typename F::value_type> result_type;
+#endif
+    };
+
+    // (outer_prod (v1, v2)) [i] [j] = v1 [i] * v2 [j]
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename vector_matrix_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type, typename E2::value_type> >::result_type
+    outer_prod (const vector_expression<E1> &e1,
+                const vector_expression<E2> &e2) {
+        BOOST_STATIC_ASSERT (E1::complexity == 0 && E2::complexity == 0);
+        typedef typename vector_matrix_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type, typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    template<class E, class F>
+    class matrix_unary1:
+        public matrix_expression<matrix_unary1<E, F> > {
+
+        typedef E expression_type;
+        typedef F functor_type;
+    public:
+        typedef typename E::const_closure_type expression_closure_type;
+    private:
+        typedef matrix_unary1<E, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef typename E::size_type size_type;
+        typedef typename E::difference_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef typename E::orientation_category orientation_category;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        explicit matrix_unary1 (const expression_type &e):
+            e_ (e) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return e_.size1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return e_.size2 ();
+        }
+
+    public:
+        // Expression accessors
+        BOOST_UBLAS_INLINE
+        const expression_closure_type &expression () const {
+            return e_;
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return functor_type::apply (e_ (i, j));
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_unary1 &mu1) const {
+            return (*this).expression ().same_closure (mu1.expression ());
+        }
+
+        // Iterator types
+    private:
+        typedef typename E::const_iterator1 const_subiterator1_type;
+        typedef typename E::const_iterator2 const_subiterator2_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator1<const_closure_type, typename const_subiterator1_type::iterator_category> const_iterator1;
+        typedef const_iterator1 iterator1;
+        typedef indexed_const_iterator2<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator2;
+        typedef const_iterator2 iterator2;
+#else
+        class const_iterator1;
+        typedef const_iterator1 iterator1;
+        class const_iterator2;
+        typedef const_iterator2 iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            const_subiterator1_type it1 (e_.find1 (rank, i, j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, it1.index1 (), it1.index2 ());
+#else
+            return const_iterator1 (*this, it1);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            const_subiterator2_type it2 (e_.find2 (rank, i, j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, it2.index1 (), it2.index2 ());
+#else
+            return const_iterator2 (*this, it2);
+#endif
+        }
+
+        // Iterators enhance the iterators of the referenced expression
+        // with the unary functor.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<matrix_unary1>,
+            public iterator_base_traits<typename E::const_iterator1::iterator_category>::template
+                iterator_base<const_iterator1, value_type>::type {
+        public:
+            typedef typename E::const_iterator1::iterator_category iterator_category;
+            typedef typename matrix_unary1::difference_type difference_type;
+            typedef typename matrix_unary1::value_type value_type;
+            typedef typename matrix_unary1::const_reference reference;
+            typedef typename matrix_unary1::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &mu, const const_subiterator1_type &it):
+                container_const_reference<self_type> (mu), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (*it_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it_.index2 ();
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator1_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<matrix_unary1>,
+            public iterator_base_traits<typename E::const_iterator2::iterator_category>::template
+                iterator_base<const_iterator2, value_type>::type {
+        public:
+            typedef typename E::const_iterator2::iterator_category iterator_category;
+            typedef typename matrix_unary1::difference_type difference_type;
+            typedef typename matrix_unary1::value_type value_type;
+            typedef typename matrix_unary1::const_reference reference;
+            typedef typename matrix_unary1::const_pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &mu, const const_subiterator2_type &it):
+                container_const_reference<self_type> (mu), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (*it_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it_.index2 ();
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator2_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+    private:
+        expression_closure_type e_;
+    };
+
+    template<class E, class F>
+    struct matrix_unary1_traits {
+        typedef matrix_unary1<E, F> expression_type;
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type; 
+#else
+        typedef typename E::matrix_temporary_type result_type;
+#endif
+    };
+
+    // (- m) [i] [j] = - m [i] [j]
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename matrix_unary1_traits<E, scalar_negate<typename E::value_type> >::result_type
+    operator - (const matrix_expression<E> &e) {
+        typedef typename matrix_unary1_traits<E, scalar_negate<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // (conj m) [i] [j] = conj (m [i] [j])
+    template<class E> 
+    BOOST_UBLAS_INLINE
+    typename matrix_unary1_traits<E, scalar_conj<typename E::value_type> >::result_type
+    conj (const matrix_expression<E> &e) {
+        typedef typename matrix_unary1_traits<E, scalar_conj<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // (real m) [i] [j] = real (m [i] [j])
+    template<class E> 
+    BOOST_UBLAS_INLINE
+    typename matrix_unary1_traits<E, scalar_real<typename E::value_type> >::result_type
+    real (const matrix_expression<E> &e) {
+        typedef typename matrix_unary1_traits<E, scalar_real<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // (imag m) [i] [j] = imag (m [i] [j])
+    template<class E> 
+    BOOST_UBLAS_INLINE
+    typename matrix_unary1_traits<E, scalar_imag<typename E::value_type> >::result_type
+    imag (const matrix_expression<E> &e) {
+        typedef typename matrix_unary1_traits<E, scalar_imag<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    template<class E, class F>
+    class matrix_unary2:
+        public matrix_expression<matrix_unary2<E, F> > {
+
+        typedef typename boost::mpl::if_<boost::is_same<F, scalar_identity<typename E::value_type> >,
+                                          E,
+                                          const E>::type expression_type;
+        typedef F functor_type;
+    public:
+        typedef typename boost::mpl::if_<boost::is_const<expression_type>,
+                                          typename E::const_closure_type,
+                                          typename E::closure_type>::type expression_closure_type;
+    private:
+        typedef matrix_unary2<E, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef typename E::size_type size_type;
+        typedef typename E::difference_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef typename boost::mpl::if_<boost::is_same<F, scalar_identity<value_type> >,
+                                          typename E::reference,
+                                          value_type>::type reference;
+
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename boost::mpl::if_<boost::is_same<typename E::orientation_category,
+                                                         row_major_tag>,
+                                          column_major_tag,
+                typename boost::mpl::if_<boost::is_same<typename E::orientation_category,
+                                                         column_major_tag>,
+                                          row_major_tag,
+                                          typename E::orientation_category>::type>::type orientation_category;
+        typedef typename E::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        // matrix_unary2 may be used as mutable expression -
+        // this is the only non const expression constructor
+        explicit matrix_unary2 (expression_type &e):
+            e_ (e) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return e_.size2 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return e_.size1 ();
+        }
+
+    public:
+        // Expression accessors
+        BOOST_UBLAS_INLINE
+        const expression_closure_type &expression () const {
+            return e_;
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return functor_type::apply (e_ (j, i));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            BOOST_STATIC_ASSERT ((boost::is_same<functor_type, scalar_identity<value_type > >::value));
+            return e_ (j, i);
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_unary2 &mu2) const {
+            return (*this).expression ().same_closure (mu2.expression ());
+        }
+
+        // Iterator types
+    private:
+        typedef typename E::const_iterator1 const_subiterator2_type;
+        typedef typename E::const_iterator2 const_subiterator1_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator1<const_closure_type, typename const_subiterator1_type::iterator_category> const_iterator1;
+        typedef const_iterator1 iterator1;
+        typedef indexed_const_iterator2<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator2;
+        typedef const_iterator2 iterator2;
+#else
+        class const_iterator1;
+        typedef const_iterator1 iterator1;
+        class const_iterator2;
+        typedef const_iterator2 iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            const_subiterator1_type it1 (e_.find2 (rank, j, i));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, it1.index2 (), it1.index1 ());
+#else
+            return const_iterator1 (*this, it1);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            const_subiterator2_type it2 (e_.find1 (rank, j, i));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, it2.index2 (), it2.index1 ());
+#else
+            return const_iterator2 (*this, it2);
+#endif
+        }
+
+        // Iterators enhance the iterators of the referenced expression
+        // with the unary functor.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<matrix_unary2>,
+            public iterator_base_traits<typename E::const_iterator2::iterator_category>::template
+                iterator_base<const_iterator1, value_type>::type {
+        public:
+            typedef typename E::const_iterator2::iterator_category iterator_category;
+            typedef typename matrix_unary2::difference_type difference_type;
+            typedef typename matrix_unary2::value_type value_type;
+            typedef typename matrix_unary2::const_reference reference;
+            typedef typename matrix_unary2::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &mu, const const_subiterator1_type &it):
+                container_const_reference<self_type> (mu), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (*it_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it_.index2 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it_.index1 ();
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator1_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<matrix_unary2>,
+            public iterator_base_traits<typename E::const_iterator1::iterator_category>::template
+                iterator_base<const_iterator2, value_type>::type {
+        public:
+            typedef typename E::const_iterator1::iterator_category iterator_category;
+            typedef typename matrix_unary2::difference_type difference_type;
+            typedef typename matrix_unary2::value_type value_type;
+            typedef typename matrix_unary2::const_reference reference;
+            typedef typename matrix_unary2::const_pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &mu, const const_subiterator2_type &it):
+                container_const_reference<self_type> (mu), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (*it_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it_.index2 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it_.index1 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator2_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+    private:
+        expression_closure_type e_;
+    };
+
+    template<class E, class F>
+    struct matrix_unary2_traits {
+        typedef matrix_unary2<E, F> expression_type;
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type; 
+#else
+        typedef typename E::matrix_temporary_type result_type;
+#endif
+    };
+
+    // (trans m) [i] [j] = m [j] [i]
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename matrix_unary2_traits<const E, scalar_identity<typename E::value_type> >::result_type
+    trans (const matrix_expression<E> &e) {
+        typedef typename matrix_unary2_traits<const E, scalar_identity<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename matrix_unary2_traits<E, scalar_identity<typename E::value_type> >::result_type
+    trans (matrix_expression<E> &e) {
+        typedef typename matrix_unary2_traits<E, scalar_identity<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // (herm m) [i] [j] = conj (m [j] [i])
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename matrix_unary2_traits<E, scalar_conj<typename E::value_type> >::result_type
+    herm (const matrix_expression<E> &e) {
+        typedef typename matrix_unary2_traits<E, scalar_conj<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    template<class E1, class E2, class F>
+    class matrix_binary:
+        public matrix_expression<matrix_binary<E1, E2, F> > {
+
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+        typedef F functor_type;
+    public:
+        typedef typename E1::const_closure_type expression1_closure_type;
+        typedef typename E2::const_closure_type expression2_closure_type;
+    private:
+        typedef matrix_binary<E1, E2, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef typename promote_traits<typename E1::size_type, typename E2::size_type>::promote_type size_type;
+        typedef typename promote_traits<typename E1::difference_type, typename E2::difference_type>::promote_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef unknown_orientation_tag orientation_category;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_binary (const E1 &e1, const E2 &e2): 
+            e1_ (e1), e2_ (e2) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const { 
+            return BOOST_UBLAS_SAME (e1_.size1 (), e2_.size1 ());
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return BOOST_UBLAS_SAME (e1_.size2 (), e2_.size2 ());
+        }
+
+    public:
+        // Expression accessors
+        BOOST_UBLAS_INLINE
+        const expression1_closure_type &expression1 () const {
+            return e1_;
+        }
+        BOOST_UBLAS_INLINE
+        const expression2_closure_type &expression2 () const {
+            return e2_;
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return functor_type::apply (e1_ (i, j), e2_ (i, j));
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_binary &mb) const {
+            return (*this).expression1 ().same_closure (mb.expression1 ()) &&
+                   (*this).expression2 ().same_closure (mb.expression2 ());
+        }
+
+        // Iterator types
+    private:
+        typedef typename E1::const_iterator1 const_iterator11_type;
+        typedef typename E1::const_iterator2 const_iterator12_type;
+        typedef typename E2::const_iterator1 const_iterator21_type;
+        typedef typename E2::const_iterator2 const_iterator22_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef typename iterator_restrict_traits<typename const_iterator11_type::iterator_category,
+                                                  typename const_iterator21_type::iterator_category>::iterator_category iterator_category1;
+        typedef indexed_const_iterator1<const_closure_type, iterator_category1> const_iterator1;
+        typedef const_iterator1 iterator1;
+        typedef typename iterator_restrict_traits<typename const_iterator12_type::iterator_category,
+                                                  typename const_iterator22_type::iterator_category>::iterator_category iterator_category2;
+        typedef indexed_const_iterator2<const_closure_type, iterator_category2> const_iterator2;
+        typedef const_iterator2 iterator2;
+#else
+        class const_iterator1;
+        typedef const_iterator1 iterator1;
+        class const_iterator2;
+        typedef const_iterator2 iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            const_iterator11_type it11 (e1_.find1 (rank, i, j));
+            const_iterator11_type it11_end (e1_.find1 (rank, size1 (), j));
+            const_iterator21_type it21 (e2_.find1 (rank, i, j));
+            const_iterator21_type it21_end (e2_.find1 (rank, size1 (), j));
+            BOOST_UBLAS_CHECK (rank == 0 || it11 == it11_end || it11.index2 () == j, internal_logic ())
+            BOOST_UBLAS_CHECK (rank == 0 || it21 == it21_end || it21.index2 () == j, internal_logic ())
+            i = (std::min) (it11 != it11_end ? it11.index1 () : size1 (),
+                          it21 != it21_end ? it21.index1 () : size1 ());
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, i, j);
+#else
+            return const_iterator1 (*this, i, j, it11, it11_end, it21, it21_end);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            const_iterator12_type it12 (e1_.find2 (rank, i, j));
+            const_iterator12_type it12_end (e1_.find2 (rank, i, size2 ()));
+            const_iterator22_type it22 (e2_.find2 (rank, i, j));
+            const_iterator22_type it22_end (e2_.find2 (rank, i, size2 ()));
+            BOOST_UBLAS_CHECK (rank == 0 || it12 == it12_end || it12.index1 () == i, internal_logic ())
+            BOOST_UBLAS_CHECK (rank == 0 || it22 == it22_end || it22.index1 () == i, internal_logic ())
+            j = (std::min) (it12 != it12_end ? it12.index2 () : size2 (),
+                          it22 != it22_end ? it22.index2 () : size2 ());
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, i, j);
+#else
+            return const_iterator2 (*this, i, j, it12, it12_end, it22, it22_end);
+#endif
+        }
+
+        // Iterators enhance the iterators of the referenced expression
+        // with the binary functor.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<matrix_binary>,
+            public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator1::iterator_category,
+                                                                          typename E2::const_iterator1::iterator_category>::iterator_category>::template
+                iterator_base<const_iterator1, value_type>::type {
+        public:
+            typedef typename iterator_restrict_traits<typename E1::const_iterator1::iterator_category,
+                                                      typename E2::const_iterator1::iterator_category>::iterator_category iterator_category;
+            typedef typename matrix_binary::difference_type difference_type;
+            typedef typename matrix_binary::value_type value_type;
+            typedef typename matrix_binary::const_reference reference;
+            typedef typename matrix_binary::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), i_ (), j_ (), it1_ (), it1_end_ (), it2_ (), it2_end_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &mb, size_type i, size_type j,
+                             const const_iterator11_type &it1, const const_iterator11_type &it1_end,
+                             const const_iterator21_type &it2, const const_iterator21_type &it2_end):
+                container_const_reference<self_type> (mb), i_ (i), j_ (j), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {}
+
+        private:
+            // Dense specializations
+            BOOST_UBLAS_INLINE
+            void increment (dense_random_access_iterator_tag) {
+                ++ i_; ++ it1_; ++ it2_;
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (dense_random_access_iterator_tag) {
+                -- i_; -- it1_; -- it2_;
+            }
+            BOOST_UBLAS_INLINE
+            void increment (dense_random_access_iterator_tag, difference_type n) {
+                 i_ += n; it1_ += n; it2_ += n;
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (dense_random_access_iterator_tag, difference_type n) {
+                i_ -= n; it1_ -= n; it2_ -= n;
+            }
+            BOOST_UBLAS_INLINE
+            value_type dereference (dense_random_access_iterator_tag) const {
+                return functor_type::apply (*it1_, *it2_);
+            }
+
+            // Packed specializations
+            BOOST_UBLAS_INLINE
+            void increment (packed_random_access_iterator_tag) {
+                if (it1_ != it1_end_)
+                    if (it1_.index1 () <= i_)
+                        ++ it1_;
+                if (it2_ != it2_end_)
+                    if (it2_.index1 () <= i_)
+                        ++ it2_;
+                ++ i_;
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (packed_random_access_iterator_tag) {
+                if (it1_ != it1_end_)
+                    if (i_ <= it1_.index1 ())
+                        -- it1_;
+                if (it2_ != it2_end_)
+                    if (i_ <= it2_.index1 ())
+                        -- it2_;
+                -- i_;
+            }
+            BOOST_UBLAS_INLINE
+            void increment (packed_random_access_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    increment (packed_random_access_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    decrement (packed_random_access_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (packed_random_access_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    decrement (packed_random_access_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    increment (packed_random_access_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            value_type dereference (packed_random_access_iterator_tag) const {
+                value_type t1 = value_type/*zero*/();
+                if (it1_ != it1_end_) {
+                    BOOST_UBLAS_CHECK (it1_.index2 () == j_, internal_logic ());
+                    if (it1_.index1 () == i_)
+                        t1 = *it1_;
+                }
+                value_type t2 = value_type/*zero*/();
+                if (it2_ != it2_end_) {
+                    BOOST_UBLAS_CHECK (it2_.index2 () == j_, internal_logic ());
+                    if (it2_.index1 () == i_)
+                        t2 = *it2_;
+                }
+                return functor_type::apply (t1, t2);
+            }
+
+            // Sparse specializations
+            BOOST_UBLAS_INLINE
+            void increment (sparse_bidirectional_iterator_tag) {
+                size_type index1 = (*this) ().size1 ();
+                if (it1_ != it1_end_) {
+                    if (it1_.index1 () <= i_)
+                        ++ it1_;
+                    if (it1_ != it1_end_)
+                        index1 = it1_.index1 ();
+                }
+                size_type index2 = (*this) ().size1 ();
+                if (it2_ != it2_end_)
+                    if (it2_.index1 () <= i_)
+                        ++ it2_;
+                    if (it2_ != it2_end_) {
+                        index2 = it2_.index1 ();
+                }
+                i_ = (std::min) (index1, index2);
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (sparse_bidirectional_iterator_tag) {
+                size_type index1 = (*this) ().size1 ();
+                if (it1_ != it1_end_) {
+                    if (i_ <= it1_.index1 ())
+                        -- it1_;
+                    if (it1_ != it1_end_)
+                        index1 = it1_.index1 ();
+                }
+                size_type index2 = (*this) ().size1 ();
+                if (it2_ != it2_end_) {
+                    if (i_ <= it2_.index1 ())
+                        -- it2_;
+                    if (it2_ != it2_end_)
+                        index2 = it2_.index1 ();
+                }
+                i_ = (std::max) (index1, index2);
+            }
+            BOOST_UBLAS_INLINE
+            void increment (sparse_bidirectional_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    increment (sparse_bidirectional_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    decrement (sparse_bidirectional_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (sparse_bidirectional_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    decrement (sparse_bidirectional_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    increment (sparse_bidirectional_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            value_type dereference (sparse_bidirectional_iterator_tag) const {
+                value_type t1 = value_type/*zero*/();
+                if (it1_ != it1_end_) {
+                    BOOST_UBLAS_CHECK (it1_.index2 () == j_, internal_logic ());
+                    if (it1_.index1 () == i_)
+                        t1 = *it1_;
+                }
+                value_type t2 = value_type/*zero*/();
+                if (it2_ != it2_end_) {
+                    BOOST_UBLAS_CHECK (it2_.index2 () == j_, internal_logic ());
+                    if (it2_.index1 () == i_)
+                        t2 = *it2_;
+                }
+                return functor_type::apply (t1, t2);
+            }
+
+        public:
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                increment (iterator_category ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                decrement (iterator_category ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                increment (iterator_category (), n);
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                decrement (iterator_category (), n);
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (index2 () == it.index2 (), external_logic ());
+                return index1 () - it.index1 ();
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return dereference (iterator_category ());
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return i_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                // if (it1_ != it1_end_ && it2_ != it2_end_)
+                //    return BOOST_UBLAS_SAME (it1_.index2 (), it2_.index2 ());
+                // else
+                    return j_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                i_ = it.i_;
+                j_ = it.j_;
+                it1_ = it.it1_;
+                it1_end_ = it.it1_end_;
+                it2_ = it.it2_;
+                it2_end_ = it.it2_end_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (index2 () == it.index2 (), external_logic ());
+                return index1 () == it.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (index2 () == it.index2 (), external_logic ());
+                return index1 () < it.index1 ();
+            }
+
+        private:
+            size_type i_;
+            size_type j_;
+            const_iterator11_type it1_;
+            const_iterator11_type it1_end_;
+            const_iterator21_type it2_;
+            const_iterator21_type it2_end_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<matrix_binary>,
+            public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator2::iterator_category,
+                                                                          typename E2::const_iterator2::iterator_category>::iterator_category>::template
+                iterator_base<const_iterator2, value_type>::type {
+        public:
+            typedef typename iterator_restrict_traits<typename E1::const_iterator2::iterator_category,
+                                                      typename E2::const_iterator2::iterator_category>::iterator_category iterator_category;
+            typedef typename matrix_binary::difference_type difference_type;
+            typedef typename matrix_binary::value_type value_type;
+            typedef typename matrix_binary::const_reference reference;
+            typedef typename matrix_binary::const_pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), i_ (), j_ (), it1_ (), it1_end_ (), it2_ (), it2_end_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &mb, size_type i, size_type j,
+                             const const_iterator12_type &it1, const const_iterator12_type &it1_end,
+                             const const_iterator22_type &it2, const const_iterator22_type &it2_end):
+                container_const_reference<self_type> (mb), i_ (i), j_ (j), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {}
+
+        private:
+            // Dense access specializations
+            BOOST_UBLAS_INLINE
+            void increment (dense_random_access_iterator_tag) {
+                ++ j_; ++ it1_; ++ it2_;
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (dense_random_access_iterator_tag) {
+                -- j_; -- it1_; -- it2_;
+            }
+            BOOST_UBLAS_INLINE
+            void increment (dense_random_access_iterator_tag, difference_type n) {
+                j_ += n; it1_ += n; it2_ += n;
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (dense_random_access_iterator_tag, difference_type n) {
+                j_ -= n; it1_ -= n; it2_ -= n;
+            }
+            BOOST_UBLAS_INLINE
+            value_type dereference (dense_random_access_iterator_tag) const {
+                return functor_type::apply (*it1_, *it2_);
+            }
+
+            // Packed specializations
+            BOOST_UBLAS_INLINE
+            void increment (packed_random_access_iterator_tag) {
+                if (it1_ != it1_end_)
+                    if (it1_.index2 () <= j_)
+                        ++ it1_;
+                if (it2_ != it2_end_)
+                    if (it2_.index2 () <= j_)
+                        ++ it2_;
+                ++ j_;
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (packed_random_access_iterator_tag) {
+                if (it1_ != it1_end_)
+                    if (j_ <= it1_.index2 ())
+                        -- it1_;
+                if (it2_ != it2_end_)
+                    if (j_ <= it2_.index2 ())
+                        -- it2_;
+                -- j_;
+            }
+            BOOST_UBLAS_INLINE
+            void increment (packed_random_access_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    increment (packed_random_access_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    decrement (packed_random_access_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (packed_random_access_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    decrement (packed_random_access_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    increment (packed_random_access_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            value_type dereference (packed_random_access_iterator_tag) const {
+                value_type t1 = value_type/*zero*/();
+                if (it1_ != it1_end_) {
+                    BOOST_UBLAS_CHECK (it1_.index1 () == i_, internal_logic ());
+                    if (it1_.index2 () == j_)
+                        t1 = *it1_;
+                }
+                value_type t2 = value_type/*zero*/();
+                if (it2_ != it2_end_) {
+                    BOOST_UBLAS_CHECK (it2_.index1 () == i_, internal_logic ());
+                    if (it2_.index2 () == j_)
+                        t2 = *it2_;
+                }
+                return functor_type::apply (t1, t2);
+            }
+
+            // Sparse specializations
+            BOOST_UBLAS_INLINE
+            void increment (sparse_bidirectional_iterator_tag) {
+                size_type index1 = (*this) ().size2 ();
+                if (it1_ != it1_end_) {
+                    if (it1_.index2 () <= j_)
+                        ++ it1_;
+                    if (it1_ != it1_end_)
+                        index1 = it1_.index2 ();
+                }
+                size_type index2 = (*this) ().size2 ();
+                if (it2_ != it2_end_) {
+                    if (it2_.index2 () <= j_)
+                        ++ it2_;
+                    if (it2_ != it2_end_)
+                        index2 = it2_.index2 ();
+                }
+                j_ = (std::min) (index1, index2);
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (sparse_bidirectional_iterator_tag) {
+                size_type index1 = (*this) ().size2 ();
+                if (it1_ != it1_end_) {
+                    if (j_ <= it1_.index2 ())
+                        -- it1_;
+                    if (it1_ != it1_end_)
+                        index1 = it1_.index2 ();
+                }
+                size_type index2 = (*this) ().size2 ();
+                if (it2_ != it2_end_) {
+                    if (j_ <= it2_.index2 ())
+                        -- it2_;
+                    if (it2_ != it2_end_)
+                        index2 = it2_.index2 ();
+                }
+                j_ = (std::max) (index1, index2);
+            }
+            BOOST_UBLAS_INLINE
+            void increment (sparse_bidirectional_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    increment (sparse_bidirectional_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    decrement (sparse_bidirectional_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (sparse_bidirectional_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    decrement (sparse_bidirectional_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    increment (sparse_bidirectional_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            value_type dereference (sparse_bidirectional_iterator_tag) const {
+                value_type t1 = value_type/*zero*/();
+                if (it1_ != it1_end_) {
+                    BOOST_UBLAS_CHECK (it1_.index1 () == i_, internal_logic ());
+                    if (it1_.index2 () == j_)
+                        t1 = *it1_;
+                }
+                value_type t2 = value_type/*zero*/();
+                if (it2_ != it2_end_) {
+                    BOOST_UBLAS_CHECK (it2_.index1 () == i_, internal_logic ());
+                    if (it2_.index2 () == j_)
+                        t2 = *it2_;
+                }
+                return functor_type::apply (t1, t2);
+            }
+
+        public:
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                increment (iterator_category ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                decrement (iterator_category ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                increment (iterator_category (), n);
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                decrement (iterator_category (), n);
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (index1 () == it.index1 (), external_logic ());
+                return index2 () - it.index2 ();
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return dereference (iterator_category ());
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                // if (it1_ != it1_end_ && it2_ != it2_end_)
+                //    return BOOST_UBLAS_SAME (it1_.index1 (), it2_.index1 ());
+                // else
+                    return i_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return j_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                i_ = it.i_;
+                j_ = it.j_;
+                it1_ = it.it1_;
+                it1_end_ = it.it1_end_;
+                it2_ = it.it2_;
+                it2_end_ = it.it2_end_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (index1 () == it.index1 (), external_logic ());
+                return index2 () == it.index2 ();
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (index1 () == it.index1 (), external_logic ());
+                return index2 () < it.index2 ();
+            }
+
+        private:
+            size_type i_;
+            size_type j_;
+            const_iterator12_type it1_;
+            const_iterator12_type it1_end_;
+            const_iterator22_type it2_;
+            const_iterator22_type it2_end_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class E1, class E2, class F>
+    struct matrix_binary_traits {
+        typedef matrix_binary<E1, E2, F> expression_type;
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type; 
+#else
+        typedef typename E1::matrix_temporary_type result_type;
+#endif
+    };
+
+    // (m1 + m2) [i] [j] = m1 [i] [j] + m2 [i] [j]
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_binary_traits<E1, E2, scalar_plus<typename E1::value_type,
+                                                      typename E2::value_type> >::result_type
+    operator + (const matrix_expression<E1> &e1,
+                const matrix_expression<E2> &e2) {
+        typedef typename matrix_binary_traits<E1, E2, scalar_plus<typename E1::value_type,
+                                                                  typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // (m1 - m2) [i] [j] = m1 [i] [j] - m2 [i] [j]
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_binary_traits<E1, E2, scalar_minus<typename E1::value_type,
+                                                       typename E2::value_type> >::result_type
+    operator - (const matrix_expression<E1> &e1,
+                const matrix_expression<E2> &e2) {
+        typedef typename matrix_binary_traits<E1, E2, scalar_minus<typename E1::value_type,
+                                                                   typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // (m1 * m2) [i] [j] = m1 [i] [j] * m2 [i] [j]
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type,
+                                                            typename E2::value_type> >::result_type
+    element_prod (const matrix_expression<E1> &e1,
+                  const matrix_expression<E2> &e2) {
+        typedef typename matrix_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type,
+                                                                        typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // (m1 / m2) [i] [j] = m1 [i] [j] / m2 [i] [j]
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_binary_traits<E1, E2, scalar_divides<typename E1::value_type,
+                                                         typename E2::value_type> >::result_type
+    element_div (const matrix_expression<E1> &e1,
+                 const matrix_expression<E2> &e2) {
+        typedef typename matrix_binary_traits<E1, E2, scalar_divides<typename E1::value_type,
+                                                                     typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    template<class E1, class E2, class F>
+    class matrix_binary_scalar1:
+        public matrix_expression<matrix_binary_scalar1<E1, E2, F> > {
+
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+        typedef F functor_type;
+        typedef const E1& expression1_closure_type;
+        typedef typename E2::const_closure_type expression2_closure_type;
+        typedef matrix_binary_scalar1<E1, E2, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef typename E2::orientation_category orientation_category;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_binary_scalar1 (const expression1_type &e1, const expression2_type &e2):
+            e1_ (e1), e2_ (e2) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return e2_.size1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return e2_.size2 ();
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return functor_type::apply (expression1_type (e1_), e2_ (i, j));
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_binary_scalar1 &mbs1) const {
+            return &e1_ == &(mbs1.e1_) &&
+                   (*this).e2_.same_closure (mbs1.e2_);
+        }
+
+        // Iterator types
+    private:
+        typedef expression1_type const_subiterator1_type;
+        typedef typename E2::const_iterator1 const_iterator21_type;
+        typedef typename E2::const_iterator2 const_iterator22_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator1<const_closure_type, typename const_iterator21_type::iterator_category> const_iterator1;
+        typedef const_iterator1 iterator1;
+        typedef indexed_const_iterator2<const_closure_type, typename const_iterator22_type::iterator_category> const_iterator2;
+        typedef const_iterator2 iterator2;
+#else
+        class const_iterator1;
+        typedef const_iterator1 iterator1;
+        class const_iterator2;
+        typedef const_iterator2 iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            const_iterator21_type it21 (e2_.find1 (rank, i, j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, it21.index1 (), it21.index2 ());
+#else
+            return const_iterator1 (*this, const_subiterator1_type (e1_), it21);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            const_iterator22_type it22 (e2_.find2 (rank, i, j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, it22.index1 (), it22.index2 ());
+#else
+            return const_iterator2 (*this, const_subiterator1_type (e1_), it22);
+#endif
+        }
+
+        // Iterators enhance the iterators of the referenced expression
+        // with the binary functor.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<matrix_binary_scalar1>,
+            public iterator_base_traits<typename E2::const_iterator1::iterator_category>::template
+                iterator_base<const_iterator1, value_type>::type {
+        public:
+            typedef typename E2::const_iterator1::iterator_category iterator_category;
+            typedef typename matrix_binary_scalar1::difference_type difference_type;
+            typedef typename matrix_binary_scalar1::value_type value_type;
+            typedef typename matrix_binary_scalar1::const_reference reference;
+            typedef typename matrix_binary_scalar1::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &mbs, const const_subiterator1_type &it1, const const_iterator21_type &it2):
+                container_const_reference<self_type> (mbs), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it2_ ;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it2_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_iterator21_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<matrix_binary_scalar1>,
+            public iterator_base_traits<typename E2::const_iterator2::iterator_category>::template
+                iterator_base<const_iterator2, value_type>::type {
+        public:
+            typedef typename E2::const_iterator2::iterator_category iterator_category;
+            typedef typename matrix_binary_scalar1::difference_type difference_type;
+            typedef typename matrix_binary_scalar1::value_type value_type;
+            typedef typename matrix_binary_scalar1::const_reference reference;
+            typedef typename matrix_binary_scalar1::const_pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &mbs, const const_subiterator1_type &it1, const const_iterator22_type &it2):
+                container_const_reference<self_type> (mbs), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it2_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_iterator22_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class E1, class E2, class F>
+    struct matrix_binary_scalar1_traits {
+        typedef matrix_binary_scalar1<E1, E2, F> expression_type;   // allow E1 to be builtin type
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type;
+#else
+        typedef typename E2::matrix_temporary_type result_type;
+#endif
+    };
+
+    // (t * m) [i] [j] = t * m [i] [j]
+    template<class T1, class E2>
+    BOOST_UBLAS_INLINE
+    typename enable_if< is_convertible<T1, typename E2::value_type >,
+    typename matrix_binary_scalar1_traits<const T1, E2, scalar_multiplies<T1, typename E2::value_type> >::result_type
+    >::type
+    operator * (const T1 &e1,
+                const matrix_expression<E2> &e2) {
+        typedef typename matrix_binary_scalar1_traits<const T1, E2, scalar_multiplies<T1, typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1, e2 ());
+    }
+
+
+    template<class E1, class E2, class F>
+    class matrix_binary_scalar2:
+        public matrix_expression<matrix_binary_scalar2<E1, E2, F> > {
+
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+        typedef F functor_type;
+    public:
+        typedef typename E1::const_closure_type expression1_closure_type;
+        typedef const E2& expression2_closure_type;
+    private:
+        typedef matrix_binary_scalar2<E1, E2, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef typename E1::size_type size_type;
+        typedef typename E1::difference_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef typename E1::orientation_category orientation_category;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_binary_scalar2 (const expression1_type &e1, const expression2_type &e2): 
+            e1_ (e1), e2_ (e2) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return e1_.size1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return e1_.size2 ();
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return functor_type::apply (e1_ (i, j), expression2_type (e2_));
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_binary_scalar2 &mbs2) const {
+            return (*this).e1_.same_closure (mbs2.e1_) &&
+                   &e2_ == &(mbs2.e2_);
+        }
+
+        // Iterator types
+    private:
+        typedef typename E1::const_iterator1 const_iterator11_type;
+        typedef typename E1::const_iterator2 const_iterator12_type;
+        typedef expression2_type const_subiterator2_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator1<const_closure_type, typename const_iterator11_type::iterator_category> const_iterator1;
+        typedef const_iterator1 iterator1;
+        typedef indexed_const_iterator2<const_closure_type, typename const_iterator12_type::iterator_category> const_iterator2;
+        typedef const_iterator2 iterator2;
+#else
+        class const_iterator1;
+        typedef const_iterator1 iterator1;
+        class const_iterator2;
+        typedef const_iterator2 iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            const_iterator11_type it11 (e1_.find1 (rank, i, j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, it11.index1 (), it11.index2 ());
+#else
+            return const_iterator1 (*this, it11, const_subiterator2_type (e2_));
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            const_iterator12_type it12 (e1_.find2 (rank, i, j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, it12.index1 (), it12.index2 ());
+#else
+            return const_iterator2 (*this, it12, const_subiterator2_type (e2_));
+#endif
+        }
+
+        // Iterators enhance the iterators of the referenced expression
+        // with the binary functor.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<matrix_binary_scalar2>,
+            public iterator_base_traits<typename E1::const_iterator1::iterator_category>::template
+                iterator_base<const_iterator1, value_type>::type {
+        public:
+            typedef typename E1::const_iterator1::iterator_category iterator_category;
+            typedef typename matrix_binary_scalar2::difference_type difference_type;
+            typedef typename matrix_binary_scalar2::value_type value_type;
+            typedef typename matrix_binary_scalar2::const_reference reference;
+            typedef typename matrix_binary_scalar2::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &mbs, const const_iterator11_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (mbs), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_ ;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (*it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it1_.index2 ();
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            const_iterator11_type it1_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<matrix_binary_scalar2>,
+            public iterator_base_traits<typename E1::const_iterator2::iterator_category>::template
+                iterator_base<const_iterator2, value_type>::type {
+        public:
+            typedef typename E1::const_iterator2::iterator_category iterator_category;
+            typedef typename matrix_binary_scalar2::difference_type difference_type;
+            typedef typename matrix_binary_scalar2::value_type value_type;
+            typedef typename matrix_binary_scalar2::const_reference reference;
+            typedef typename matrix_binary_scalar2::const_pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &mbs, const const_iterator12_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (mbs), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (*it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it1_.index2 ();
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            const_iterator12_type it1_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class E1, class E2, class F>
+    struct matrix_binary_scalar2_traits {
+        typedef matrix_binary_scalar2<E1, E2, F> expression_type;   // allow E2 to be builtin type
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type; 
+#else
+        typedef typename E1::matrix_temporary_type result_type;
+#endif
+    };
+
+    // (m * t) [i] [j] = m [i] [j] * t
+    template<class E1, class T2>
+    BOOST_UBLAS_INLINE
+    typename enable_if< is_convertible<T2, typename E1::value_type>,
+    typename matrix_binary_scalar2_traits<E1, const T2, scalar_multiplies<typename E1::value_type, T2> >::result_type
+    >::type
+    operator * (const matrix_expression<E1> &e1,
+                const T2 &e2) {
+        typedef typename matrix_binary_scalar2_traits<E1, const T2, scalar_multiplies<typename E1::value_type, T2> >::expression_type expression_type;
+        return expression_type (e1 (), e2);
+    }
+
+    // (m / t) [i] [j] = m [i] [j] / t
+    template<class E1, class T2>
+    BOOST_UBLAS_INLINE
+    typename enable_if< is_convertible<T2, typename E1::value_type>,
+    typename matrix_binary_scalar2_traits<E1, const T2, scalar_divides<typename E1::value_type, T2> >::result_type
+    >::type
+    operator / (const matrix_expression<E1> &e1,
+                const T2 &e2) {
+        typedef typename matrix_binary_scalar2_traits<E1, const T2, scalar_divides<typename E1::value_type, T2> >::expression_type expression_type;
+        return expression_type (e1 (), e2);
+    }
+
+
+    template<class E1, class E2, class F>
+    class matrix_vector_binary1:
+        public vector_expression<matrix_vector_binary1<E1, E2, F> > {
+
+    public:
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+    private:
+        typedef F functor_type;
+    public:
+        typedef typename E1::const_closure_type expression1_closure_type;
+        typedef typename E2::const_closure_type expression2_closure_type;
+    private:
+        typedef matrix_vector_binary1<E1, E2, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<self_type>::operator ();
+#endif
+        static const unsigned complexity = 1;
+        typedef typename promote_traits<typename E1::size_type, typename E2::size_type>::promote_type size_type;
+        typedef typename promote_traits<typename E1::difference_type, typename E2::difference_type>::promote_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_vector_binary1 (const expression1_type &e1, const expression2_type &e2):
+            e1_ (e1), e2_ (e2) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return e1_.size1 ();
+        }
+
+    public:
+        // Expression accessors
+        BOOST_UBLAS_INLINE
+        const expression1_closure_type &expression1 () const {
+            return e1_;
+        }
+        BOOST_UBLAS_INLINE
+        const expression2_closure_type &expression2 () const {
+            return e2_;
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return functor_type::apply (e1_, e2_, i);
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_vector_binary1 &mvb1) const {
+            return (*this).expression1 ().same_closure (mvb1.expression1 ()) &&
+                   (*this).expression2 ().same_closure (mvb1.expression2 ());
+        }
+
+        // Iterator types
+    private:
+        typedef typename E1::const_iterator1 const_subiterator1_type;
+        typedef typename E2::const_iterator const_subiterator2_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator<const_closure_type, typename const_subiterator1_type::iterator_category> const_iterator;
+        typedef const_iterator iterator;
+#else
+        class const_iterator;
+        typedef const_iterator iterator;
+#endif
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            const_subiterator1_type it1 (e1_.find1 (0, i, 0));
+            return const_iterator (*this, it1.index1 ());
+#else
+            return const_iterator (*this, e1_.find1 (0, i, 0));
+#endif
+        }
+
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<matrix_vector_binary1>,
+            public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator1::iterator_category,
+                                                                          typename E2::const_iterator::iterator_category>::iterator_category>::template
+                iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename iterator_restrict_traits<typename E1::const_iterator1::iterator_category, 
+                                                      typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
+            typedef typename matrix_vector_binary1::difference_type difference_type;
+            typedef typename matrix_vector_binary1::value_type value_type;
+            typedef typename matrix_vector_binary1::const_reference reference;
+            typedef typename matrix_vector_binary1::const_pointer pointer;
+
+            // Construction and destruction
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it1_ (), e2_begin_ (), e2_end_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &mvb, const const_subiterator1_type &it1):
+                container_const_reference<self_type> (mvb), it1_ (it1), e2_begin_ (mvb.expression2 ().begin ()), e2_end_ (mvb.expression2 ().end ()) {}
+#else
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it1_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &mvb, const const_subiterator1_type &it1):
+                container_const_reference<self_type> (mvb), it1_ (it1) {}
+#endif
+
+        private:
+            // Dense random access specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (dense_random_access_iterator_tag) const {
+                const self_type &mvb = (*this) ();
+#ifdef BOOST_UBLAS_USE_INDEXING
+                return mvb (index ());
+#elif BOOST_UBLAS_USE_ITERATING
+                difference_type size = BOOST_UBLAS_SAME (mvb.expression1 ().size2 (), mvb.expression2 ().size ());
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (size, it1_.begin (), e2_begin_);
+#else
+                return functor_type::apply (size, it1_.begin (), mvb.expression2 ().begin ());
+#endif
+#else
+                difference_type size = BOOST_UBLAS_SAME (mvb.expression1 ().size2 (), mvb.expression2 ().size ());
+                if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                    return functor_type::apply (size, it1_.begin (), e2_begin_);
+#else
+                    return functor_type::apply (size, it1_.begin (), mvb.expression2 ().begin ());
+#endif
+                else
+                    return mvb (index ());
+#endif
+            }
+
+            // Packed bidirectional specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (packed_random_access_iterator_tag) const {
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (it1_.begin (), it1_.end (), e2_begin_, e2_end_);
+#else
+                const self_type &mvb = (*this) ();
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                return functor_type::apply (it1_.begin (), it1_.end (),
+                                        mvb.expression2 ().begin (), mvb.expression2 ().end ());
+#else
+                return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()),
+                                        boost::numeric::ublas::end (it1_, iterator1_tag ()),
+                                        mvb.expression2 ().begin (), mvb.expression2 ().end ());
+#endif
+#endif
+            }
+
+            // Sparse bidirectional specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (sparse_bidirectional_iterator_tag) const {
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (it1_.begin (), it1_.end (), e2_begin_, e2_end_, sparse_bidirectional_iterator_tag ());
+#else
+                const self_type &mvb = (*this) ();
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                return functor_type::apply (it1_.begin (), it1_.end (),
+                                        mvb.expression2 ().begin (), mvb.expression2 ().end (), sparse_bidirectional_iterator_tag ());
+#else
+                return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()),
+                                        boost::numeric::ublas::end (it1_, iterator1_tag ()),
+                                        mvb.expression2 ().begin (), mvb.expression2 ().end (), sparse_bidirectional_iterator_tag ());
+#endif
+#endif
+            }
+
+        public:
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return dereference (iterator_category ());
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it1_.index1 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                e2_begin_ = it.e2_begin_;
+                e2_end_ = it.e2_end_;
+#endif
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            // Mutable due to assignment
+            /* const */ const_subiterator2_type e2_begin_;
+            /* const */ const_subiterator2_type e2_end_;
+#endif
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ()); 
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class T1, class E1, class T2, class E2>
+    struct matrix_vector_binary1_traits {
+        typedef unknown_storage_tag storage_category;
+        typedef row_major_tag orientation_category;
+        typedef typename promote_traits<T1, T2>::promote_type promote_type;
+        typedef matrix_vector_binary1<E1, E2, matrix_vector_prod1<E1, E2, promote_type> > expression_type;
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type;
+#else
+        typedef typename E1::vector_temporary_type result_type;
+#endif
+    };
+
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_vector_binary1_traits<typename E1::value_type, E1,
+                                          typename E2::value_type, E2>::result_type
+    prod (const matrix_expression<E1> &e1,
+          const vector_expression<E2> &e2,
+          unknown_storage_tag,
+          row_major_tag) {
+        typedef typename matrix_vector_binary1_traits<typename E1::value_type, E1,
+                                                      typename E2::value_type, E2>::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_vector_binary1_traits<typename E1::value_type, E1,
+                                          typename E2::value_type, E2>::result_type
+    prod (const matrix_expression<E1> &e1,
+          const vector_expression<E2> &e2) {
+        BOOST_STATIC_ASSERT (E2::complexity == 0);
+        typedef typename matrix_vector_binary1_traits<typename E1::value_type, E1,
+                                                      typename E2::value_type, E2>::storage_category storage_category;
+        typedef typename matrix_vector_binary1_traits<typename E1::value_type, E1,
+                                                      typename E2::value_type, E2>::orientation_category orientation_category;
+        return prod (e1, e2, storage_category (), orientation_category ());
+    }
+
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_vector_binary1_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                          typename type_traits<typename E2::value_type>::precision_type, E2>::result_type
+    prec_prod (const matrix_expression<E1> &e1,
+               const vector_expression<E2> &e2,
+               unknown_storage_tag,
+               row_major_tag) {
+        typedef typename matrix_vector_binary1_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                                      typename type_traits<typename E2::value_type>::precision_type, E2>::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_vector_binary1_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                          typename type_traits<typename E2::value_type>::precision_type, E2>::result_type
+    prec_prod (const matrix_expression<E1> &e1,
+               const vector_expression<E2> &e2) {
+        BOOST_STATIC_ASSERT (E2::complexity == 0);
+        typedef typename matrix_vector_binary1_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                                      typename type_traits<typename E2::value_type>::precision_type, E2>::storage_category storage_category;
+        typedef typename matrix_vector_binary1_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                                      typename type_traits<typename E2::value_type>::precision_type, E2>::orientation_category orientation_category;
+        return prec_prod (e1, e2, storage_category (), orientation_category ());
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    prod (const matrix_expression<E1> &e1,
+          const vector_expression<E2> &e2,
+          V &v) {
+        return v.assign (prod (e1, e2));
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    prec_prod (const matrix_expression<E1> &e1,
+               const vector_expression<E2> &e2,
+               V &v) {
+        return v.assign (prec_prod (e1, e2));
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V
+    prod (const matrix_expression<E1> &e1,
+          const vector_expression<E2> &e2) {
+        return V (prod (e1, e2));
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V
+    prec_prod (const matrix_expression<E1> &e1,
+               const vector_expression<E2> &e2) {
+        return V (prec_prod (e1, e2));
+    }
+
+    template<class E1, class E2, class F>
+    class matrix_vector_binary2:
+        public vector_expression<matrix_vector_binary2<E1, E2, F> > {
+
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+        typedef F functor_type;
+    public:
+        typedef typename E1::const_closure_type expression1_closure_type;
+        typedef typename E2::const_closure_type expression2_closure_type;
+    private:
+        typedef matrix_vector_binary2<E1, E2, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<self_type>::operator ();
+#endif
+        static const unsigned complexity = 1;
+        typedef typename promote_traits<typename E1::size_type, typename E2::size_type>::promote_type size_type;
+        typedef typename promote_traits<typename E1::difference_type, typename E2::difference_type>::promote_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_vector_binary2 (const expression1_type &e1, const expression2_type &e2): 
+            e1_ (e1), e2_ (e2) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const { 
+            return e2_.size2 (); 
+        }
+
+    public:
+        // Expression accessors
+        BOOST_UBLAS_INLINE
+        const expression1_closure_type &expression1 () const {
+            return e1_;
+        }
+        BOOST_UBLAS_INLINE
+        const expression2_closure_type &expression2 () const {
+            return e2_;
+        }
+    public:
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type j) const { 
+            return functor_type::apply (e1_, e2_, j); 
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_vector_binary2 &mvb2) const {
+            return (*this).expression1 ().same_closure (mvb2.expression1 ()) &&
+                   (*this).expression2 ().same_closure (mvb2.expression2 ());
+        }
+
+        // Iterator types
+    private:
+        typedef typename E1::const_iterator const_subiterator1_type;
+        typedef typename E2::const_iterator2 const_subiterator2_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator;
+        typedef const_iterator iterator;
+#else
+        class const_iterator;
+        typedef const_iterator iterator;
+#endif
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            const_subiterator2_type it2 (e2_.find2 (0, 0, j));
+            return const_iterator (*this, it2.index2 ());
+#else
+            return const_iterator (*this, e2_.find2 (0, 0, j));
+#endif
+        }
+
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<matrix_vector_binary2>,
+            public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
+                                                                          typename E2::const_iterator2::iterator_category>::iterator_category>::template
+                iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
+                                                      typename E2::const_iterator2::iterator_category>::iterator_category iterator_category;
+            typedef typename matrix_vector_binary2::difference_type difference_type;
+            typedef typename matrix_vector_binary2::value_type value_type;
+            typedef typename matrix_vector_binary2::const_reference reference;
+            typedef typename matrix_vector_binary2::const_pointer pointer;
+
+            // Construction and destruction
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it2_ (), e1_begin_ (), e1_end_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &mvb, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (mvb), it2_ (it2), e1_begin_ (mvb.expression1 ().begin ()), e1_end_ (mvb.expression1 ().end ()) {}
+#else
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &mvb, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (mvb), it2_ (it2) {}
+#endif
+
+        private:
+            // Dense random access specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (dense_random_access_iterator_tag) const {
+                const self_type &mvb = (*this) ();
+#ifdef BOOST_UBLAS_USE_INDEXING
+                return mvb (index ());
+#elif BOOST_UBLAS_USE_ITERATING
+                difference_type size = BOOST_UBLAS_SAME (mvb.expression2 ().size1 (), mvb.expression1 ().size ());
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (size, e1_begin_, it2_.begin ());
+#else
+                return functor_type::apply (size, mvb.expression1 ().begin (), it2_.begin ());
+#endif
+#else
+                difference_type size = BOOST_UBLAS_SAME (mvb.expression2 ().size1 (), mvb.expression1 ().size ());
+                if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                    return functor_type::apply (size, e1_begin_, it2_.begin ());
+#else
+                    return functor_type::apply (size, mvb.expression1 ().begin (), it2_.begin ());
+#endif
+                else
+                    return mvb (index ());
+#endif
+            }
+
+            // Packed bidirectional specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (packed_random_access_iterator_tag) const {
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (e1_begin_, e1_end_, it2_.begin (), it2_.end ());
+#else
+                const self_type &mvb = (*this) ();
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (),
+                                        it2_.begin (), it2_.end ());
+#else
+                return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (),
+                                        boost::numeric::ublas::begin (it2_, iterator2_tag ()),
+                                        boost::numeric::ublas::end (it2_, iterator2_tag ()));
+#endif
+#endif
+            }
+
+            // Sparse bidirectional specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (sparse_bidirectional_iterator_tag) const {
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (e1_begin_, e1_end_, it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ());
+#else
+                const self_type &mvb = (*this) ();
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (),
+                                        it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ());
+#else
+                return functor_type::apply (mvb.expression1 ().begin (), mvb.expression1 ().end (),
+                                        boost::numeric::ublas::begin (it2_, iterator2_tag ()),
+                                        boost::numeric::ublas::end (it2_, iterator2_tag ()), sparse_bidirectional_iterator_tag ());
+#endif
+#endif
+            }
+
+        public:
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return dereference (iterator_category ());
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it2_ = it.it2_;
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                e1_begin_ = it.e1_begin_;
+                e1_end_ = it.e1_end_;
+#endif
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator2_type it2_;
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            // Mutable due to assignment 
+            /* const */ const_subiterator1_type e1_begin_;
+            /* const */ const_subiterator1_type e1_end_;
+#endif
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ()); 
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class T1, class E1, class T2, class E2>
+    struct matrix_vector_binary2_traits {
+        typedef unknown_storage_tag storage_category;
+        typedef column_major_tag orientation_category;
+        typedef typename promote_traits<T1, T2>::promote_type promote_type;
+        typedef matrix_vector_binary2<E1, E2, matrix_vector_prod2<E1, E2, promote_type> > expression_type;
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type;
+#else
+        typedef typename E2::vector_temporary_type result_type;
+#endif
+    };
+
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_vector_binary2_traits<typename E1::value_type, E1,
+                                          typename E2::value_type, E2>::result_type
+    prod (const vector_expression<E1> &e1,
+          const matrix_expression<E2> &e2,
+          unknown_storage_tag,
+          column_major_tag) {
+        typedef typename matrix_vector_binary2_traits<typename E1::value_type, E1,
+                                                      typename E2::value_type, E2>::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_vector_binary2_traits<typename E1::value_type, E1,
+                                          typename E2::value_type, E2>::result_type
+    prod (const vector_expression<E1> &e1,
+          const matrix_expression<E2> &e2) {
+        BOOST_STATIC_ASSERT (E1::complexity == 0);
+        typedef typename matrix_vector_binary2_traits<typename E1::value_type, E1,
+                                                      typename E2::value_type, E2>::storage_category storage_category;
+        typedef typename matrix_vector_binary2_traits<typename E1::value_type, E1,
+                                                      typename E2::value_type, E2>::orientation_category orientation_category;
+        return prod (e1, e2, storage_category (), orientation_category ());
+    }
+
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_vector_binary2_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                          typename type_traits<typename E2::value_type>::precision_type, E2>::result_type
+    prec_prod (const vector_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               unknown_storage_tag,
+               column_major_tag) {
+        typedef typename matrix_vector_binary2_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                                      typename type_traits<typename E2::value_type>::precision_type, E2>::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_vector_binary2_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                          typename type_traits<typename E2::value_type>::precision_type, E2>::result_type
+    prec_prod (const vector_expression<E1> &e1,
+               const matrix_expression<E2> &e2) {
+        BOOST_STATIC_ASSERT (E1::complexity == 0);
+        typedef typename matrix_vector_binary2_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                                      typename type_traits<typename E2::value_type>::precision_type, E2>::storage_category storage_category;
+        typedef typename matrix_vector_binary2_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                                      typename type_traits<typename E2::value_type>::precision_type, E2>::orientation_category orientation_category;
+        return prec_prod (e1, e2, storage_category (), orientation_category ());
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    prod (const vector_expression<E1> &e1,
+          const matrix_expression<E2> &e2,
+          V &v) {
+        return v.assign (prod (e1, e2));
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    prec_prod (const vector_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               V &v) {
+        return v.assign (prec_prod (e1, e2));
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V
+    prod (const vector_expression<E1> &e1,
+          const matrix_expression<E2> &e2) {
+        return V (prod (e1, e2));
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V
+    prec_prod (const vector_expression<E1> &e1,
+               const matrix_expression<E2> &e2) {
+        return V (prec_prod (e1, e2));
+    }
+
+    template<class E1, class E2, class F>
+    class matrix_matrix_binary:
+        public matrix_expression<matrix_matrix_binary<E1, E2, F> > {
+
+    public:
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+    private:
+        typedef F functor_type;
+    public:
+        typedef typename E1::const_closure_type expression1_closure_type;
+        typedef typename E2::const_closure_type expression2_closure_type;
+    private:
+        typedef matrix_matrix_binary<E1, E2, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        static const unsigned complexity = 1;
+        typedef typename promote_traits<typename E1::size_type, typename E2::size_type>::promote_type size_type;
+        typedef typename promote_traits<typename E1::difference_type, typename E2::difference_type>::promote_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef unknown_orientation_tag orientation_category;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_matrix_binary (const expression1_type &e1, const expression2_type &e2):
+            e1_ (e1), e2_ (e2) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return e1_.size1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return e2_.size2 ();
+        }
+
+    public:
+        // Expression accessors
+        BOOST_UBLAS_INLINE
+        const expression1_closure_type &expression1 () const {
+            return e1_;
+        }
+        BOOST_UBLAS_INLINE
+        const expression2_closure_type &expression2 () const {
+            return e2_;
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return functor_type::apply (e1_, e2_, i, j);
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_matrix_binary &mmb) const {
+            return (*this).expression1 ().same_closure (mmb.expression1 ()) &&
+                   (*this).expression2 ().same_closure (mmb.expression2 ());
+        }
+
+        // Iterator types
+    private:
+        typedef typename E1::const_iterator1 const_iterator11_type;
+        typedef typename E1::const_iterator2 const_iterator12_type;
+        typedef typename E2::const_iterator1 const_iterator21_type;
+        typedef typename E2::const_iterator2 const_iterator22_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef typename iterator_restrict_traits<typename const_iterator11_type::iterator_category,
+                                                  typename const_iterator22_type::iterator_category>::iterator_category iterator_category;
+        typedef indexed_const_iterator1<const_closure_type, iterator_category> const_iterator1;
+        typedef const_iterator1 iterator1;
+        typedef indexed_const_iterator2<const_closure_type, iterator_category> const_iterator2;
+        typedef const_iterator2 iterator2;
+#else
+        class const_iterator1;
+        typedef const_iterator1 iterator1;
+        class const_iterator2;
+        typedef const_iterator2 iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
+            // FIXME sparse matrix tests fail!
+            // const_iterator11_type it11 (e1_.find1 (rank, i, 0));
+            const_iterator11_type it11 (e1_.find1 (0, i, 0));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, it11.index1 (), j);
+#else
+            // FIXME sparse matrix tests fail!
+            // const_iterator22_type it22 (e2_.find2 (rank, 0, j));
+            const_iterator22_type it22 (e2_.find2 (0, 0, j));
+            return const_iterator1 (*this, it11, it22);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
+            // FIXME sparse matrix tests fail!
+            // const_iterator22_type it22 (e2_.find2 (rank, 0, j));
+            const_iterator22_type it22 (e2_.find2 (0, 0, j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, i, it22.index2 ());
+#else
+            // FIXME sparse matrix tests fail!
+            // const_iterator11_type it11 (e1_.find1 (rank, i, 0));
+            const_iterator11_type it11 (e1_.find1 (0, i, 0));
+            return const_iterator2 (*this, it11, it22);
+#endif
+        }
+
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<matrix_matrix_binary>,
+            public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator1::iterator_category,
+                                                                          typename E2::const_iterator2::iterator_category>::iterator_category>::template
+                iterator_base<const_iterator1, value_type>::type {
+        public:
+            typedef typename iterator_restrict_traits<typename E1::const_iterator1::iterator_category,
+                                                      typename E2::const_iterator2::iterator_category>::iterator_category iterator_category;
+            typedef typename matrix_matrix_binary::difference_type difference_type;
+            typedef typename matrix_matrix_binary::value_type value_type;
+            typedef typename matrix_matrix_binary::const_reference reference;
+            typedef typename matrix_matrix_binary::const_pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ (), it2_begin_ (), it2_end_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &mmb, const const_iterator11_type &it1, const const_iterator22_type &it2):
+                container_const_reference<self_type> (mmb), it1_ (it1), it2_ (it2), it2_begin_ (it2.begin ()), it2_end_ (it2.end ()) {}
+#else
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &mmb, const const_iterator11_type &it1, const const_iterator22_type &it2):
+                container_const_reference<self_type> (mmb), it1_ (it1), it2_ (it2) {}
+#endif
+
+        private:
+            // Random access specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (dense_random_access_iterator_tag) const {
+                const self_type &mmb = (*this) ();
+#ifdef BOOST_UBLAS_USE_INDEXING
+                return mmb (index1 (), index2 ());
+#elif BOOST_UBLAS_USE_ITERATING
+                difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ());
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (size, it1_.begin (), it2_begin_);
+#else
+                return functor_type::apply (size, it1_.begin (), it2_.begin ());
+#endif
+#else
+                difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ());
+                if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                    return functor_type::apply (size, it1_.begin (), it2_begin_);
+#else
+                    return functor_type::apply (size, it1_.begin (), it2_.begin ());
+#endif
+                else
+                    return mmb (index1 (), index2 ());
+#endif
+            }
+
+            // Packed bidirectional specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (packed_random_access_iterator_tag) const {
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (it1_.begin (), it1_.end (),
+                                        it2_begin_, it2_end_, packed_random_access_iterator_tag ());
+#else
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                return functor_type::apply (it1_.begin (), it1_.end (),
+                                        it2_.begin (), it2_.end (), packed_random_access_iterator_tag ());
+#else
+                return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()),
+                                        boost::numeric::ublas::end (it1_, iterator1_tag ()),
+                                        boost::numeric::ublas::begin (it2_, iterator2_tag ()),
+                                        boost::numeric::ublas::end (it2_, iterator2_tag ()), packed_random_access_iterator_tag ());
+#endif
+#endif
+            }
+
+            // Sparse bidirectional specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (sparse_bidirectional_iterator_tag) const {
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (it1_.begin (), it1_.end (),
+                                        it2_begin_, it2_end_, sparse_bidirectional_iterator_tag ());
+#else
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                return functor_type::apply (it1_.begin (), it1_.end (),
+                                        it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ());
+#else
+                return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()),
+                                        boost::numeric::ublas::end (it1_, iterator1_tag ()),
+                                        boost::numeric::ublas::begin (it2_, iterator2_tag ()),
+                                        boost::numeric::ublas::end (it2_, iterator2_tag ()), sparse_bidirectional_iterator_tag ());
+#endif
+#endif
+            }
+
+        public:
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return dereference (iterator_category ());
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                it2_begin_ = it.it2_begin_;
+                it2_end_ = it.it2_end_;
+#endif
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            const_iterator11_type it1_;
+            // Mutable due to assignment
+            /* const */ const_iterator22_type it2_;
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            /* const */ const_iterator21_type it2_begin_;
+            /* const */ const_iterator21_type it2_end_;
+#endif
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<matrix_matrix_binary>,
+            public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator1::iterator_category,
+                                                                          typename E2::const_iterator2::iterator_category>::iterator_category>::template
+                iterator_base<const_iterator2, value_type>::type {
+        public:
+            typedef typename iterator_restrict_traits<typename E1::const_iterator1::iterator_category,
+                                                      typename E2::const_iterator2::iterator_category>::iterator_category iterator_category;
+            typedef typename matrix_matrix_binary::difference_type difference_type;
+            typedef typename matrix_matrix_binary::value_type value_type;
+            typedef typename matrix_matrix_binary::const_reference reference;
+            typedef typename matrix_matrix_binary::const_pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ (), it1_begin_ (), it1_end_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &mmb, const const_iterator11_type &it1, const const_iterator22_type &it2):
+                container_const_reference<self_type> (mmb), it1_ (it1), it2_ (it2), it1_begin_ (it1.begin ()), it1_end_ (it1.end ()) {}
+#else
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &mmb, const const_iterator11_type &it1, const const_iterator22_type &it2):
+                container_const_reference<self_type> (mmb), it1_ (it1), it2_ (it2) {}
+#endif
+
+        private:
+            // Random access specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (dense_random_access_iterator_tag) const {
+                const self_type &mmb = (*this) ();
+#ifdef BOOST_UBLAS_USE_INDEXING
+                return mmb (index1 (), index2 ());
+#elif BOOST_UBLAS_USE_ITERATING
+                difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ());
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (size, it1_begin_, it2_.begin ());
+#else
+                return functor_type::apply (size, it1_.begin (), it2_.begin ());
+#endif
+#else
+                difference_type size = BOOST_UBLAS_SAME (mmb.expression1 ().size2 (), mmb.expression2 ().size1 ());
+                if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                    return functor_type::apply (size, it1_begin_, it2_.begin ());
+#else
+                    return functor_type::apply (size, it1_.begin (), it2_.begin ());
+#endif
+                else
+                    return mmb (index1 (), index2 ());
+#endif
+            }
+
+            // Packed bidirectional specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (packed_random_access_iterator_tag) const {
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (it1_begin_, it1_end_,
+                                        it2_.begin (), it2_.end (), packed_random_access_iterator_tag ());
+#else
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                return functor_type::apply (it1_.begin (), it1_.end (),
+                                        it2_.begin (), it2_.end (), packed_random_access_iterator_tag ());
+#else
+                return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()),
+                                        boost::numeric::ublas::end (it1_, iterator1_tag ()),
+                                        boost::numeric::ublas::begin (it2_, iterator2_tag ()),
+                                        boost::numeric::ublas::end (it2_, iterator2_tag ()), packed_random_access_iterator_tag ());
+#endif
+#endif
+            }
+
+            // Sparse bidirectional specialization
+            BOOST_UBLAS_INLINE
+            value_type dereference (sparse_bidirectional_iterator_tag) const {
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                return functor_type::apply (it1_begin_, it1_end_,
+                                        it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ());
+#else
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+                return functor_type::apply (it1_.begin (), it1_.end (),
+                                        it2_.begin (), it2_.end (), sparse_bidirectional_iterator_tag ());
+#else
+                return functor_type::apply (boost::numeric::ublas::begin (it1_, iterator1_tag ()),
+                                        boost::numeric::ublas::end (it1_, iterator1_tag ()),
+                                        boost::numeric::ublas::begin (it2_, iterator2_tag ()),
+                                        boost::numeric::ublas::end (it2_, iterator2_tag ()), sparse_bidirectional_iterator_tag ());
+#endif
+#endif
+            }
+
+        public:
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return dereference (iterator_category ());
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+                it1_begin_ = it.it1_begin_;
+                it1_end_ = it.it1_end_;
+#endif
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            // Mutable due to assignment
+            /* const */ const_iterator11_type it1_;
+            const_iterator22_type it2_;
+#ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING
+            /* const */ const_iterator12_type it1_begin_;
+            /* const */ const_iterator12_type it1_end_;
+#endif
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class T1, class E1, class T2, class E2>
+    struct matrix_matrix_binary_traits {
+        typedef unknown_storage_tag storage_category;
+        typedef unknown_orientation_tag orientation_category;
+        typedef typename promote_traits<T1, T2>::promote_type promote_type;
+        typedef matrix_matrix_binary<E1, E2, matrix_matrix_prod<E1, E2, promote_type> > expression_type;
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type;
+#else
+        typedef typename E1::matrix_temporary_type result_type;
+#endif
+    };
+
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_matrix_binary_traits<typename E1::value_type, E1,
+                                         typename E2::value_type, E2>::result_type
+    prod (const matrix_expression<E1> &e1,
+          const matrix_expression<E2> &e2,
+          unknown_storage_tag,
+          unknown_orientation_tag) {
+        typedef typename matrix_matrix_binary_traits<typename E1::value_type, E1,
+                                                     typename E2::value_type, E2>::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_matrix_binary_traits<typename E1::value_type, E1,
+                                         typename E2::value_type, E2>::result_type
+    prod (const matrix_expression<E1> &e1,
+          const matrix_expression<E2> &e2) {
+        BOOST_STATIC_ASSERT (E1::complexity == 0 && E2::complexity == 0);
+        typedef typename matrix_matrix_binary_traits<typename E1::value_type, E1,
+                                                     typename E2::value_type, E2>::storage_category storage_category;
+        typedef typename matrix_matrix_binary_traits<typename E1::value_type, E1,
+                                                     typename E2::value_type, E2>::orientation_category orientation_category;
+        return prod (e1, e2, storage_category (), orientation_category ());
+    }
+
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_matrix_binary_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                         typename type_traits<typename E2::value_type>::precision_type, E2>::result_type
+    prec_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               unknown_storage_tag,
+               unknown_orientation_tag) {
+        typedef typename matrix_matrix_binary_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                                     typename type_traits<typename E2::value_type>::precision_type, E2>::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename matrix_matrix_binary_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                         typename type_traits<typename E2::value_type>::precision_type, E2>::result_type
+    prec_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2) {
+        BOOST_STATIC_ASSERT (E1::complexity == 0 && E2::complexity == 0);
+        typedef typename matrix_matrix_binary_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                                     typename type_traits<typename E2::value_type>::precision_type, E2>::storage_category storage_category;
+        typedef typename matrix_matrix_binary_traits<typename type_traits<typename E1::value_type>::precision_type, E1,
+                                                     typename type_traits<typename E2::value_type>::precision_type, E2>::orientation_category orientation_category;
+        return prec_prod (e1, e2, storage_category (), orientation_category ());
+    }
+
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M &
+    prod (const matrix_expression<E1> &e1,
+          const matrix_expression<E2> &e2,
+          M &m) {
+        return m.assign (prod (e1, e2));
+    }
+
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M &
+    prec_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               M &m) {
+        return m.assign (prec_prod (e1, e2));
+    }
+
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M
+    prod (const matrix_expression<E1> &e1,
+          const matrix_expression<E2> &e2) {
+        return M (prod (e1, e2));
+    }
+
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M
+    prec_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2) {
+        return M (prec_prod (e1, e2));
+    }
+
+    template<class E, class F>
+    class matrix_scalar_unary:
+        public scalar_expression<matrix_scalar_unary<E, F> > {
+    public:
+        typedef E expression_type;
+        typedef F functor_type;
+        typedef typename F::result_type value_type;
+        typedef typename E::const_closure_type expression_closure_type;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        explicit matrix_scalar_unary (const expression_type &e):
+            e_ (e) {}
+
+    private:
+        // Expression accessors
+        BOOST_UBLAS_INLINE
+        const expression_closure_type &expression () const {
+            return e_;
+        }
+
+    public:
+        BOOST_UBLAS_INLINE
+        operator value_type () const {
+            return functor_type::apply (e_);
+        }
+
+    private:
+        expression_closure_type e_;
+    };
+
+    template<class E, class F>
+    struct matrix_scalar_unary_traits {
+        typedef matrix_scalar_unary<E, F> expression_type;
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+         typedef expression_type result_type;
+#else
+         typedef typename F::result_type result_type;
+#endif
+    };
+
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename matrix_scalar_unary_traits<E, matrix_norm_1<E> >::result_type
+    norm_1 (const matrix_expression<E> &e) {
+        typedef typename matrix_scalar_unary_traits<E, matrix_norm_1<E> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename matrix_scalar_unary_traits<E, matrix_norm_frobenius<E> >::result_type
+    norm_frobenius (const matrix_expression<E> &e) {
+        typedef typename matrix_scalar_unary_traits<E, matrix_norm_frobenius<E> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename matrix_scalar_unary_traits<E, matrix_norm_inf<E> >::result_type
+    norm_inf (const matrix_expression<E> &e) {
+        typedef typename matrix_scalar_unary_traits<E, matrix_norm_inf<E> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/matrix_proxy.hpp b/include/boost/numeric/ublas/matrix_proxy.hpp
new file mode 100644
index 0000000..25b7f93
--- /dev/null
+++ b/include/boost/numeric/ublas/matrix_proxy.hpp
@@ -0,0 +1,5457 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_MATRIX_PROXY_
+#define _BOOST_UBLAS_MATRIX_PROXY_
+
+#include <boost/numeric/ublas/matrix_expression.hpp>
+#include <boost/numeric/ublas/detail/vector_assign.hpp>
+#include <boost/numeric/ublas/detail/matrix_assign.hpp>
+#include <boost/numeric/ublas/detail/temporary.hpp>
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+
+    /** \brief 
+     */
+    template<class M>
+    class matrix_row:
+        public vector_expression<matrix_row<M> > {
+
+        typedef matrix_row<M> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<self_type>::operator ();
+#endif
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_row (matrix_type &data, size_type i):
+            data_ (data), i_ (i) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (i_ < data_.size1 (), bad_index ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return data_.size2 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type index () const {
+            return i_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type j) const {
+            return data_ (i_, j);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type j) {
+            return data_ (i_, j);
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type j) const {
+            return (*this) (j);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type j) {
+            return (*this) (j);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type j) const {
+            return data_ (i_, j);
+        }
+
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type j) const {
+            return (*this) (j);
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        matrix_row &operator = (const matrix_row &mr) {
+            // ISSUE need a temporary, proxy can be overlaping alias
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mr));
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_row &assign_temporary (matrix_row &mr) {
+            // assign elements, proxied container remains the same
+            vector_assign<scalar_assign> (*this, mr);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_row &operator = (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_row &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_row &operator += (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_row &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_row &operator -= (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_row &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_row &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_row &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_row &mr) const {
+            return (*this).data_.same_closure (mr.data_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const matrix_row &mr) const {
+            return (*this).data_ == mr.data_ && index () == mr.index ();
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (matrix_row mr) {
+            if (this != &mr) {
+                BOOST_UBLAS_CHECK (size () == mr.size (), bad_size ());
+                // Sparse ranges may be nonconformant now.
+                // std::swap_ranges (begin (), end (), mr.begin ());
+                vector_swap<scalar_swap> (*this, mr);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (matrix_row mr1, matrix_row mr2) {
+            mr1.swap (mr2);
+        }
+
+        // Iterator types
+    private:
+        typedef typename M::const_iterator2 const_subiterator_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator2,
+                                          typename M::iterator2>::type subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator<matrix_row<matrix_type>,
+                                 typename subiterator_type::iterator_category> iterator;
+        typedef indexed_const_iterator<matrix_row<matrix_type>,
+                                       typename const_subiterator_type::iterator_category> const_iterator;
+#else
+        class const_iterator;
+        class iterator;
+#endif
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type j) const {
+            const_subiterator_type it2 (data_.find2 (1, i_, j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator (*this, it2.index2 ());
+#else
+            return const_iterator (*this, it2);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator find (size_type j) {
+            subiterator_type it2 (data_.find2 (1, i_, j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator (*this, it2.index2 ());
+#else
+            return iterator (*this, it2);
+#endif
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<matrix_row>,
+            public iterator_base_traits<typename const_subiterator_type::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename const_subiterator_type::value_type value_type;
+            typedef typename const_subiterator_type::difference_type difference_type;
+            typedef typename const_subiterator_type::reference reference;
+            typedef typename const_subiterator_type::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &mr, const const_subiterator_type &it):
+                container_const_reference<self_type> (mr), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator:
+            public container_reference<matrix_row>,
+            public iterator_base_traits<typename subiterator_type::iterator_category>::template
+                        iterator_base<iterator, value_type>::type {
+        public:
+            typedef typename subiterator_type::value_type value_type;
+            typedef typename subiterator_type::difference_type difference_type;
+            typedef typename subiterator_type::reference reference;
+            typedef typename subiterator_type::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &mr, const subiterator_type &it):
+                container_reference<self_type> (mr), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (size ());
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        size_type i_;
+    };
+
+    // Projections
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_row<M> row (M &data, typename M::size_type i) {
+        return matrix_row<M> (data, i);
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    const matrix_row<const M> row (const M &data, typename M::size_type i) {
+        return matrix_row<const M> (data, i);
+    }
+
+    // Specialize temporary
+    template <class M>
+    struct vector_temporary_traits< matrix_row<M> >
+    : vector_temporary_traits< M > {} ;
+    template <class M>
+    struct vector_temporary_traits< const matrix_row<M> >
+    : vector_temporary_traits< M > {} ;
+
+    // Matrix based column vector class
+    template<class M>
+    class matrix_column:
+        public vector_expression<matrix_column<M> > {
+
+        typedef matrix_column<M> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<self_type>::operator ();
+#endif
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_column (matrix_type &data, size_type j):
+            data_ (data), j_ (j) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (j_ < data_.size2 (), bad_index ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return data_.size1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type index () const {
+            return j_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return data_ (i, j_);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            return data_ (i, j_);
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) const {
+            return data_ (i, j_);
+        }
+
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        matrix_column &operator = (const matrix_column &mc) {
+            // ISSUE need a temporary, proxy can be overlaping alias
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mc));
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_column &assign_temporary (matrix_column &mc) {
+            // assign elements, proxied container remains the same
+            vector_assign<scalar_assign> (*this, mc);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_column &operator = (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_column &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_column &operator += (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_column &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_column &operator -= (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_column &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_column &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_column &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_column &mc) const {
+            return (*this).data_.same_closure (mc.data_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const matrix_column &mc) const {
+            return (*this).data_ == mc.data_ && index () == mc.index ();
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (matrix_column mc) {
+            if (this != &mc) {
+                BOOST_UBLAS_CHECK (size () == mc.size (), bad_size ());
+                // Sparse ranges may be nonconformant now.
+                // std::swap_ranges (begin (), end (), mc.begin ());
+                vector_swap<scalar_swap> (*this, mc);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (matrix_column mc1, matrix_column mc2) {
+            mc1.swap (mc2);
+        }
+
+        // Iterator types
+    private:
+        typedef typename M::const_iterator1 const_subiterator_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator1,
+                                          typename M::iterator1>::type subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator<matrix_column<matrix_type>,
+                                 typename subiterator_type::iterator_category> iterator;
+        typedef indexed_const_iterator<matrix_column<matrix_type>,
+                                       typename const_subiterator_type::iterator_category> const_iterator;
+#else
+        class const_iterator;
+        class iterator;
+#endif
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+            const_subiterator_type it1 (data_.find1 (1, i, j_));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator (*this, it1.index1 ());
+#else
+            return const_iterator (*this, it1);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator find (size_type i) {
+            subiterator_type it1 (data_.find1 (1, i, j_));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator (*this, it1.index1 ());
+#else
+            return iterator (*this, it1);
+#endif
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<matrix_column>,
+            public iterator_base_traits<typename const_subiterator_type::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename const_subiterator_type::value_type value_type;
+            typedef typename const_subiterator_type::difference_type difference_type;
+            typedef typename const_subiterator_type::reference reference;
+            typedef typename const_subiterator_type::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &mc, const const_subiterator_type &it):
+                container_const_reference<self_type> (mc), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index1 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator:
+            public container_reference<matrix_column>,
+            public iterator_base_traits<typename subiterator_type::iterator_category>::template
+                        iterator_base<iterator, value_type>::type {
+        public:
+            typedef typename subiterator_type::value_type value_type;
+            typedef typename subiterator_type::difference_type difference_type;
+            typedef typename subiterator_type::reference reference;
+            typedef typename subiterator_type::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &mc, const subiterator_type &it):
+                container_reference<self_type> (mc), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index1 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (size ());
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        size_type j_;
+    };
+
+    // Projections
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_column<M> column (M &data, typename M::size_type j) {
+        return matrix_column<M> (data, j);
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    const matrix_column<const M> column (const M &data, typename M::size_type j) {
+        return matrix_column<const M> (data, j);
+    }
+
+    // Specialize temporary
+    template <class M>
+    struct vector_temporary_traits< matrix_column<M> >
+    : vector_temporary_traits< M > {} ;
+    template <class M>
+    struct vector_temporary_traits< const matrix_column<M> >
+    : vector_temporary_traits< M > {} ;
+
+    // Matrix based vector range class
+    template<class M>
+    class matrix_vector_range:
+        public vector_expression<matrix_vector_range<M> > {
+
+        typedef matrix_vector_range<M> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<self_type>::operator ();
+#endif
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef basic_range<size_type, difference_type> range_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_vector_range (matrix_type &data, const range_type &r1, const range_type &r2):
+            data_ (data), r1_ (r1.preprocess (data.size1 ())), r2_ (r2.preprocess (data.size2 ())) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (r1_.start () <= data_.size1 () &&
+            //                     r1_.start () + r1_.size () <= data_.size1 (), bad_index ());
+            // BOOST_UBLAS_CHECK (r2_.start () <= data_.size2 () &&
+            //                   r2_.start () + r2_.size () <= data_.size2 (), bad_index ());
+            // BOOST_UBLAS_CHECK (r1_.size () == r2_.size (), bad_size ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type start1 () const {
+            return r1_.start ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type start2 () const {
+            return r2_.start ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return BOOST_UBLAS_SAME (r1_.size (), r2_.size ());
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return data_ (r1_ (i), r2_ (i));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            return data_ (r1_ (i), r2_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) const {
+            return data_ (r1_ (i), r2_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        matrix_vector_range &operator = (const matrix_vector_range &mvr) {
+            // ISSUE need a temporary, proxy can be overlaping alias
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mvr));
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_vector_range &assign_temporary (matrix_vector_range &mvr) {
+            // assign elements, proxied container remains the same
+            vector_assign<scalar_assign> (*this, mvr);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_range &operator = (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_range &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_range &operator += (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_range &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_range &operator -= (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_range &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_vector_range &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_vector_range &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_vector_range &mvr) const {
+            return (*this).data_.same_closure (mvr.data_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const matrix_vector_range &mvr) const {
+            return (*this).data_ == mvr.data_ && r1_ == mvr.r1_ && r2_ == mvr.r2_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (matrix_vector_range mvr) {
+            if (this != &mvr) {
+                BOOST_UBLAS_CHECK (size () == mvr.size (), bad_size ());
+                // Sparse ranges may be nonconformant now.
+                // std::swap_ranges (begin (), end (), mvr.begin ());
+                vector_swap<scalar_swap> (*this, mvr);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (matrix_vector_range mvr1, matrix_vector_range mvr2) {
+            mvr1.swap (mvr2);
+        }
+
+        // Iterator types
+    private:
+        // Use range as an index - FIXME this fails for packed assignment
+        typedef typename range_type::const_iterator const_subiterator1_type;
+        typedef typename range_type::const_iterator subiterator1_type;
+        typedef typename range_type::const_iterator const_subiterator2_type;
+        typedef typename range_type::const_iterator subiterator2_type;
+
+    public:
+        class const_iterator;
+        class iterator;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+            return const_iterator (*this, r1_.begin () + i, r2_.begin () + i);
+        }
+        BOOST_UBLAS_INLINE
+        iterator find (size_type i) {
+            return iterator (*this, r1_.begin () + i, r2_.begin () + i);
+        }
+
+        class const_iterator:
+            public container_const_reference<matrix_vector_range>,
+            public iterator_base_traits<typename M::const_iterator1::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            // FIXME Iterator can never be different code was:
+            // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
+            BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
+
+            typedef typename matrix_vector_range::value_type value_type;
+            typedef typename matrix_vector_range::difference_type difference_type;
+            typedef typename matrix_vector_range::const_reference reference;
+            typedef const typename matrix_vector_range::value_type *pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &mvr, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (mvr), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it1_;
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it1_;
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it1_ += n;
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it1_ -= n;
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type  index () const {
+                return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ == it.it1_ && it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ < it.it1_ && it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        class iterator:
+            public container_reference<matrix_vector_range>,
+            public iterator_base_traits<typename M::iterator1::iterator_category>::template
+                        iterator_base<iterator, value_type>::type {
+        public:
+            // FIXME Iterator can never be different code was:
+            // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
+            BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
+
+            typedef typename matrix_vector_range::value_type value_type;
+            typedef typename matrix_vector_range::difference_type difference_type;
+            typedef typename matrix_vector_range::reference reference;
+            typedef typename matrix_vector_range::value_type *pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &mvr, const subiterator1_type &it1, const subiterator2_type &it2):
+                container_reference<self_type> (mvr), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it1_;
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it1_;
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator += (difference_type n) {
+                it1_ += n;
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -= (difference_type n) {
+                it1_ -= n;
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ == it.it1_ && it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ < it.it1_ && it2_ < it.it2_;
+            }
+
+        private:
+            subiterator1_type it1_;
+            subiterator2_type it2_;
+
+            friend class const_iterator;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (size ());
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        range_type r1_;
+        range_type r2_;
+    };
+
+    // Specialize temporary
+    template <class M>
+    struct vector_temporary_traits< matrix_vector_range<M> >
+    : vector_temporary_traits< M > {} ;
+    template <class M>
+    struct vector_temporary_traits< const matrix_vector_range<M> >
+    : vector_temporary_traits< M > {} ;
+
+    // Matrix based vector slice class
+    template<class M>
+    class matrix_vector_slice:
+        public vector_expression<matrix_vector_slice<M> > {
+
+        typedef matrix_vector_slice<M> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<self_type>::operator ();
+#endif
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef basic_range<size_type, difference_type> range_type;
+        typedef basic_slice<size_type, difference_type> slice_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice (matrix_type &data, const slice_type &s1, const slice_type &s2):
+            data_ (data), s1_ (s1.preprocess (data.size1 ())), s2_ (s2.preprocess (data.size2 ())) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (s1_.start () <= data_.size1 () &&
+            //                    s1_.start () + s1_.stride () * (s1_.size () - (s1_.size () > 0)) <= data_.size1 (), bad_index ());
+            // BOOST_UBLAS_CHECK (s2_.start () <= data_.size2 () &&
+            //                    s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type start1 () const {
+            return s1_.start ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type start2 () const {
+            return s2_.start ();
+        }
+        BOOST_UBLAS_INLINE
+        difference_type stride1 () const {
+            return s1_.stride ();
+        }
+        BOOST_UBLAS_INLINE
+        difference_type stride2 () const {
+            return s2_.stride ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return BOOST_UBLAS_SAME (s1_.size (), s2_.size ());
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return data_ (s1_ (i), s2_ (i));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            return data_ (s1_ (i), s2_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) const {
+            return data_ (s1_ (i), s2_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice &operator = (const matrix_vector_slice &mvs) {
+            // ISSUE need a temporary, proxy can be overlaping alias
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mvs));
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice &assign_temporary (matrix_vector_slice &mvs) {
+            // assign elements, proxied container remains the same
+            vector_assign<scalar_assign> (*this, mvs);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice &operator = (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice &operator += (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice &operator -= (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_vector_slice &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_vector_slice &mvs) const {
+            return (*this).data_.same_closure (mvs.data_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const matrix_vector_slice &mvs) const {
+            return (*this).data_ == mvs.data_ && s1_ == mvs.s1_ && s2_ == mvs.s2_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (matrix_vector_slice mvs) {
+            if (this != &mvs) {
+                BOOST_UBLAS_CHECK (size () == mvs.size (), bad_size ());
+                // Sparse ranges may be nonconformant now.
+                // std::swap_ranges (begin (), end (), mvs.begin ());
+                vector_swap<scalar_swap> (*this, mvs);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (matrix_vector_slice mvs1, matrix_vector_slice mvs2) {
+            mvs1.swap (mvs2);
+        }
+
+        // Iterator types
+    private:
+        // Use slice as an index - FIXME this fails for packed assignment
+        typedef typename slice_type::const_iterator const_subiterator1_type;
+        typedef typename slice_type::const_iterator subiterator1_type;
+        typedef typename slice_type::const_iterator const_subiterator2_type;
+        typedef typename slice_type::const_iterator subiterator2_type;
+
+    public:
+        class const_iterator;
+        class iterator;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+            return const_iterator (*this, s1_.begin () + i, s2_.begin () + i);
+        }
+        BOOST_UBLAS_INLINE
+        iterator find (size_type i) {
+            return iterator (*this, s1_.begin () + i, s2_.begin () + i);
+        }
+
+        // Iterators simply are indices.
+
+        class const_iterator:
+            public container_const_reference<matrix_vector_slice>,
+            public iterator_base_traits<typename M::const_iterator1::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            // FIXME Iterator can never be different code was:
+            // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
+            BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
+
+            typedef typename matrix_vector_slice::value_type value_type;
+            typedef typename matrix_vector_slice::difference_type difference_type;
+            typedef typename matrix_vector_slice::const_reference reference;
+            typedef const typename matrix_vector_slice::value_type *pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &mvs, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (mvs), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE vector:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it1_;
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it1_;
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it1_ += n;
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it1_ -= n;
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type  index () const {
+                return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ == it.it1_ && it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ < it.it1_ && it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        class iterator:
+            public container_reference<matrix_vector_slice>,
+            public iterator_base_traits<typename M::iterator1::iterator_category>::template
+                        iterator_base<iterator, value_type>::type {
+        public:
+            // FIXME Iterator can never be different code was:
+            // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
+            BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
+
+            typedef typename matrix_vector_slice::value_type value_type;
+            typedef typename matrix_vector_slice::difference_type difference_type;
+            typedef typename matrix_vector_slice::reference reference;
+            typedef typename matrix_vector_slice::value_type *pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &mvs, const subiterator1_type &it1, const subiterator2_type &it2):
+                container_reference<self_type> (mvs), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it1_;
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it1_;
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator += (difference_type n) {
+                it1_ += n;
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -= (difference_type n) {
+                it1_ -= n;
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ == it.it1_ && it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ < it.it1_ && it2_ < it.it2_;
+            }
+
+        private:
+            subiterator1_type it1_;
+            subiterator2_type it2_;
+
+            friend class const_iterator;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (size ());
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        slice_type s1_;
+        slice_type s2_;
+    };
+
+    // Specialize temporary
+    template <class M>
+    struct vector_temporary_traits< matrix_vector_slice<M> >
+    : vector_temporary_traits< M > {} ;
+    template <class M>
+    struct vector_temporary_traits< const matrix_vector_slice<M> >
+    : vector_temporary_traits< M > {} ;
+
+    // Matrix based vector indirection class
+
+    template<class M, class IA>
+    class matrix_vector_indirect:
+        public vector_expression<matrix_vector_indirect<M, IA> > {
+
+        typedef matrix_vector_indirect<M, IA> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<self_type>::operator ();
+#endif
+        typedef M matrix_type;
+        typedef IA indirect_array_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect (matrix_type &data, size_type size):
+            data_ (data), ia1_ (size), ia2_ (size) {}
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect (matrix_type &data, const indirect_array_type &ia1, const indirect_array_type &ia2):
+            data_ (data), ia1_ (ia1), ia2_ (ia2) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (ia1_.size () == ia2_.size (), bad_size ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return BOOST_UBLAS_SAME (ia1_.size (), ia2_.size ());
+        }
+        BOOST_UBLAS_INLINE
+        const indirect_array_type &indirect1 () const {
+            return ia1_;
+        }
+        BOOST_UBLAS_INLINE
+        indirect_array_type &indirect1 () {
+            return ia1_;
+        }
+        BOOST_UBLAS_INLINE
+        const indirect_array_type &indirect2 () const {
+            return ia2_;
+        }
+        BOOST_UBLAS_INLINE
+        indirect_array_type &indirect2 () {
+            return ia2_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return data_ (ia1_ (i), ia2_ (i));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            return data_ (ia1_ (i), ia2_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) const {
+            return data_ (ia1_ (i), ia2_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect &operator = (const matrix_vector_indirect &mvi) {
+            // ISSUE need a temporary, proxy can be overlaping alias
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (mvi));
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect &assign_temporary (matrix_vector_indirect &mvi) {
+            // assign elements, proxied container remains the same
+            vector_assign<scalar_assign> (*this, mvi);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect &operator = (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect &operator += (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect &operator -= (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<M>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_vector_indirect &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_vector_indirect &mvi) const {
+            return (*this).data_.same_closure (mvi.data_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const matrix_vector_indirect &mvi) const {
+            return (*this).data_ == mvi.data_ && ia1_ == mvi.ia1_ && ia2_ == mvi.ia2_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (matrix_vector_indirect mvi) {
+            if (this != &mvi) {
+                BOOST_UBLAS_CHECK (size () == mvi.size (), bad_size ());
+                // Sparse ranges may be nonconformant now.
+                // std::swap_ranges (begin (), end (), mvi.begin ());
+                vector_swap<scalar_swap> (*this, mvi);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (matrix_vector_indirect mvi1, matrix_vector_indirect mvi2) {
+            mvi1.swap (mvi2);
+        }
+
+        // Iterator types
+    private:
+        // Use indirect array as an index - FIXME this fails for packed assignment
+        typedef typename IA::const_iterator const_subiterator1_type;
+        typedef typename IA::const_iterator subiterator1_type;
+        typedef typename IA::const_iterator const_subiterator2_type;
+        typedef typename IA::const_iterator subiterator2_type;
+
+    public:
+        class const_iterator;
+        class iterator;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+            return const_iterator (*this, ia1_.begin () + i, ia2_.begin () + i);
+        }
+        BOOST_UBLAS_INLINE
+        iterator find (size_type i) {
+            return iterator (*this, ia1_.begin () + i, ia2_.begin () + i);
+        }
+
+        // Iterators simply are indices.
+
+        class const_iterator:
+            public container_const_reference<matrix_vector_indirect>,
+            public iterator_base_traits<typename M::const_iterator1::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            // FIXME Iterator can never be different code was:
+            // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
+            BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
+
+            typedef typename matrix_vector_indirect::value_type value_type;
+            typedef typename matrix_vector_indirect::difference_type difference_type;
+            typedef typename matrix_vector_indirect::const_reference reference;
+            typedef const typename matrix_vector_indirect::value_type *pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &mvi, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (mvi), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it1_;
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it1_;
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it1_ += n;
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it1_ -= n;
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type  index () const {
+                return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ == it.it1_ && it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ < it.it1_ && it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        class iterator:
+            public container_reference<matrix_vector_indirect>,
+            public iterator_base_traits<typename M::iterator1::iterator_category>::template
+                        iterator_base<iterator, value_type>::type {
+        public:
+            // FIXME Iterator can never be different code was:
+            // typename iterator_restrict_traits<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::iterator_category>
+            BOOST_STATIC_ASSERT ((boost::is_same<typename M::const_iterator1::iterator_category, typename M::const_iterator2::iterator_category>::value ));
+
+            typedef typename matrix_vector_indirect::value_type value_type;
+            typedef typename matrix_vector_indirect::difference_type difference_type;
+            typedef typename matrix_vector_indirect::reference reference;
+            typedef typename matrix_vector_indirect::value_type *pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &mvi, const subiterator1_type &it1, const subiterator2_type &it2):
+                container_reference<self_type> (mvi), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it1_;
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it1_;
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator += (difference_type n) {
+                it1_ += n;
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -= (difference_type n) {
+                it1_ -= n;
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return BOOST_UBLAS_SAME (it1_ - it.it1_, it2_ - it.it2_);
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return BOOST_UBLAS_SAME (it1_.index (), it2_.index ());
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ == it.it1_ && it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it1_ < it.it1_ && it2_ < it.it2_;
+            }
+
+        private:
+            subiterator1_type it1_;
+            subiterator2_type it2_;
+
+            friend class const_iterator;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (size ());
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        indirect_array_type ia1_;
+        indirect_array_type ia2_;
+    };
+
+    // Specialize temporary
+    template <class M, class IA>
+    struct vector_temporary_traits< matrix_vector_indirect<M,IA> >
+    : vector_temporary_traits< M > {} ;
+    template <class M, class IA>
+    struct vector_temporary_traits< const matrix_vector_indirect<M,IA> >
+    : vector_temporary_traits< M > {} ;
+
+    // Matrix based range class
+    template<class M>
+    class matrix_range:
+        public matrix_expression<matrix_range<M> > {
+
+        typedef matrix_range<M> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef basic_range<size_type, difference_type> range_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_range (matrix_type &data, const range_type &r1, const range_type &r2):
+            data_ (data), r1_ (r1.preprocess (data.size1 ())), r2_ (r2.preprocess (data.size2 ())) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (r1_.start () <= data_.size1 () &&
+            //                    r1_.start () + r1_.size () <= data_.size1 (), bad_index ());
+            // BOOST_UBLAS_CHECK (r2_.start () <= data_.size2 () &&
+            //                    r2_.start () + r2_.size () <= data_.size2 (), bad_index ());
+        }
+        BOOST_UBLAS_INLINE
+        matrix_range (const matrix_closure_type &data, const range_type &r1, const range_type &r2, int):
+            data_ (data), r1_ (r1.preprocess (data.size1 ())), r2_ (r2.preprocess (data.size2 ())) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (r1_.start () <= data_.size1 () &&
+            //                    r1_.start () + r1_.size () <= data_.size1 (), bad_index ());
+            // BOOST_UBLAS_CHECK (r2_.start () <= data_.size2 () &&
+            //                    r2_.start () + r2_.size () <= data_.size2 (), bad_index ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type start1 () const {
+            return r1_.start ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return r1_.size ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type start2() const {
+            return r2_.start ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return r2_.size ();
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return data_ (r1_ (i), r2_ (j));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            return data_ (r1_ (i), r2_ (j));
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) const {
+            return data_ (r1_ (i), r2_ (j));
+        }
+#endif
+
+        // ISSUE can this be done in free project function?
+        // Although a const function can create a non-const proxy to a non-const object
+        // Critical is that matrix_type and data_ (vector_closure_type) are const correct
+        BOOST_UBLAS_INLINE
+        matrix_range<matrix_type> project (const range_type &r1, const range_type &r2) const {
+            return matrix_range<matrix_type>  (data_, r1_.compose (r1.preprocess (data_.size1 ())), r2_.compose (r2.preprocess (data_.size2 ())), 0);
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        matrix_range &operator = (const matrix_range &mr) {
+            matrix_assign<scalar_assign> (*this, mr);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_range &assign_temporary (matrix_range &mr) {
+            return *this = mr;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_range &operator = (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_range &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_range& operator += (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_range &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_range& operator -= (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_range &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_range& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_range& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_range &mr) const {
+            return (*this).data_.same_closure (mr.data_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const matrix_range &mr) const {
+            return (*this).data_ == (mr.data_) && r1_ == mr.r1_ && r2_ == mr.r2_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (matrix_range mr) {
+            if (this != &mr) {
+                BOOST_UBLAS_CHECK (size1 () == mr.size1 (), bad_size ());
+                BOOST_UBLAS_CHECK (size2 () == mr.size2 (), bad_size ());
+                matrix_swap<scalar_swap> (*this, mr);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (matrix_range mr1, matrix_range mr2) {
+            mr1.swap (mr2);
+        }
+
+        // Iterator types
+    private:
+        typedef typename M::const_iterator1 const_subiterator1_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator1,
+                                          typename M::iterator1>::type subiterator1_type;
+        typedef typename M::const_iterator2 const_subiterator2_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator2,
+                                          typename M::iterator2>::type subiterator2_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<matrix_range<matrix_type>,
+                                  typename subiterator1_type::iterator_category> iterator1;
+        typedef indexed_iterator2<matrix_range<matrix_type>,
+                                  typename subiterator2_type::iterator_category> iterator2;
+        typedef indexed_const_iterator1<matrix_range<matrix_type>,
+                                        typename const_subiterator1_type::iterator_category> const_iterator1;
+        typedef indexed_const_iterator2<matrix_range<matrix_type>,
+                                        typename const_subiterator2_type::iterator_category> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            const_subiterator1_type it1 (data_.find1 (rank, start1 () + i, start2 () + j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, it1.index1 (), it1.index2 ());
+#else
+            return const_iterator1 (*this, it1);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int rank, size_type i, size_type j) {
+            subiterator1_type it1 (data_.find1 (rank, start1 () + i, start2 () + j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator1 (*this, it1.index1 (), it1.index2 ());
+#else
+            return iterator1 (*this, it1);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            const_subiterator2_type it2 (data_.find2 (rank, start1 () + i, start2 () + j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, it2.index1 (), it2.index2 ());
+#else
+            return const_iterator2 (*this, it2);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int rank, size_type i, size_type j) {
+            subiterator2_type it2 (data_.find2 (rank, start1 () + i, start2 () + j));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator2 (*this, it2.index1 (), it2.index2 ());
+#else
+            return iterator2 (*this, it2);
+#endif
+        }
+
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<matrix_range>,
+            public iterator_base_traits<typename const_subiterator1_type::iterator_category>::template
+                        iterator_base<const_iterator1, value_type>::type {
+        public:
+            typedef typename const_subiterator1_type::value_type value_type;
+            typedef typename const_subiterator1_type::difference_type difference_type;
+            typedef typename const_subiterator1_type::reference reference;
+            typedef typename const_subiterator1_type::pointer pointer;
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &mr, const const_subiterator1_type &it):
+                container_const_reference<self_type> (mr), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const self_type &mr = (*this) ();
+                return mr.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const self_type &mr = (*this) ();
+                return mr.find2 (1, index1 (), mr.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it_.index1 () - (*this) ().start1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it_.index2 () - (*this) ().start2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator1_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<matrix_range>,
+            public iterator_base_traits<typename subiterator1_type::iterator_category>::template
+                        iterator_base<iterator1, value_type>::type {
+        public:
+            typedef typename subiterator1_type::value_type value_type;
+            typedef typename subiterator1_type::difference_type difference_type;
+            typedef typename subiterator1_type::reference reference;
+            typedef typename subiterator1_type::pointer pointer;
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &mr, const subiterator1_type &it):
+                container_reference<self_type> (mr), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                self_type &mr = (*this) ();
+                return mr.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                self_type &mr = (*this) ();
+                return mr.find2 (1, index1 (), mr.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it_.index1 () - (*this) ().start1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it_.index2 () - (*this) ().start2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator1_type it_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1 (), 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<matrix_range>,
+            public iterator_base_traits<typename const_subiterator2_type::iterator_category>::template
+                        iterator_base<const_iterator2, value_type>::type {
+        public:
+            typedef typename const_subiterator2_type::value_type value_type;
+            typedef typename const_subiterator2_type::difference_type difference_type;
+            typedef typename const_subiterator2_type::reference reference;
+            typedef typename const_subiterator2_type::pointer pointer;
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &mr, const const_subiterator2_type &it):
+                container_const_reference<self_type> (mr), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const self_type &mr = (*this) ();
+                return mr.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const self_type &mr = (*this) ();
+                return mr.find1 (1, mr.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it_.index1 () - (*this) ().start1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it_.index2 () - (*this) ().start2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator2_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<matrix_range>,
+            public iterator_base_traits<typename subiterator2_type::iterator_category>::template
+                        iterator_base<iterator2, value_type>::type {
+        public:
+            typedef typename subiterator2_type::value_type value_type;
+            typedef typename subiterator2_type::difference_type difference_type;
+            typedef typename subiterator2_type::reference reference;
+            typedef typename subiterator2_type::pointer pointer;
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &mr, const subiterator2_type &it):
+                container_reference<self_type> (mr), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+               BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                self_type &mr = (*this) ();
+                return mr.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                self_type &mr = (*this) ();
+                return mr.find1 (1, mr.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it_.index1 () - (*this) ().start1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it_.index2 () - (*this) ().start2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator2_type it_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2 ());
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        range_type r1_;
+        range_type r2_;
+    };
+
+    // Simple Projections
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_range<M> subrange (M &data, typename M::size_type start1, typename M::size_type stop1, typename M::size_type start2, typename M::size_type stop2) {
+        typedef basic_range<typename M::size_type, typename M::difference_type> range_type;
+        return matrix_range<M> (data, range_type (start1, stop1), range_type (start2, stop2));
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_range<const M> subrange (const M &data, typename M::size_type start1, typename M::size_type stop1, typename M::size_type start2, typename M::size_type stop2) {
+        typedef basic_range<typename M::size_type, typename M::difference_type> range_type;
+        return matrix_range<const M> (data, range_type (start1, stop1), range_type (start2, stop2));
+    }
+
+    // Generic Projections
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_range<M> project (M &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
+        return matrix_range<M> (data, r1, r2);
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    const matrix_range<const M> project (const M &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
+        // ISSUE was: return matrix_range<M> (const_cast<M &> (data), r1, r2);
+        return matrix_range<const M> (data, r1, r2);
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_range<M> project (matrix_range<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
+        return data.project (r1, r2);
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    const matrix_range<M> project (const matrix_range<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
+        return data.project (r1, r2);
+    }
+
+    // Specialization of temporary_traits
+    template <class M>
+    struct matrix_temporary_traits< matrix_range<M> >
+    : matrix_temporary_traits< M > {} ;
+    template <class M>
+    struct matrix_temporary_traits< const matrix_range<M> >
+    : matrix_temporary_traits< M > {} ;
+
+    template <class M>
+    struct vector_temporary_traits< matrix_range<M> >
+    : vector_temporary_traits< M > {} ;
+    template <class M>
+    struct vector_temporary_traits< const matrix_range<M> >
+    : vector_temporary_traits< M > {} ;
+
+    // Matrix based slice class
+    template<class M>
+    class matrix_slice:
+        public matrix_expression<matrix_slice<M> > {
+
+        typedef matrix_slice<M> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef basic_range<size_type, difference_type> range_type;
+        typedef basic_slice<size_type, difference_type> slice_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_slice (matrix_type &data, const slice_type &s1, const slice_type &s2):
+            data_ (data), s1_ (s1.preprocess (data.size1 ())), s2_ (s2.preprocess (data.size2 ())) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (s1_.start () <= data_.size1 () &&
+            //                    s1_.start () + s1_.stride () * (s1_.size () - (s1_.size () > 0)) <= data_.size1 (), bad_index ());
+            // BOOST_UBLAS_CHECK (s2_.start () <= data_.size2 () &&
+            //                    s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ());
+        }
+        BOOST_UBLAS_INLINE
+        matrix_slice (const matrix_closure_type &data, const slice_type &s1, const slice_type &s2, int):
+            data_ (data), s1_ (s1.preprocess (data.size1 ())), s2_ (s2.preprocess (data.size2 ())) {
+            // Early checking of preconditions.
+            // BOOST_UBLAS_CHECK (s1_.start () <= data_.size1 () &&
+            //                    s1_.start () + s1_.stride () * (s1_.size () - (s1_.size () > 0)) <= data_.size1 (), bad_index ());
+            // BOOST_UBLAS_CHECK (s2_.start () <= data_.size2 () &&
+            //                    s2_.start () + s2_.stride () * (s2_.size () - (s2_.size () > 0)) <= data_.size2 (), bad_index ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type start1 () const {
+            return s1_.start ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type start2 () const {
+            return s2_.start ();
+        }
+        BOOST_UBLAS_INLINE
+        difference_type stride1 () const {
+            return s1_.stride ();
+        }
+        BOOST_UBLAS_INLINE
+        difference_type stride2 () const {
+            return s2_.stride ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return s1_.size ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return s2_.size ();
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return data_ (s1_ (i), s2_ (j));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            return data_ (s1_ (i), s2_ (j));
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) const {
+            return data_ (s1_ (i), s2_ (j));
+        }
+#endif
+
+        // ISSUE can this be done in free project function?
+        // Although a const function can create a non-const proxy to a non-const object
+        // Critical is that matrix_type and data_ (vector_closure_type) are const correct
+        BOOST_UBLAS_INLINE
+        matrix_slice<matrix_type> project (const range_type &r1, const range_type &r2) const {
+            return matrix_slice<matrix_type>  (data_, s1_.compose (r1.preprocess (data_.size1 ())), s2_.compose (r2.preprocess (data_.size2 ())), 0);
+        }
+        BOOST_UBLAS_INLINE
+        matrix_slice<matrix_type> project (const slice_type &s1, const slice_type &s2) const {
+            return matrix_slice<matrix_type>  (data_, s1_.compose (s1.preprocess (data_.size1 ())), s2_.compose (s2.preprocess (data_.size2 ())), 0);
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        matrix_slice &operator = (const matrix_slice &ms) {
+            matrix_assign<scalar_assign> (*this, ms);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_slice &assign_temporary (matrix_slice &ms) {
+            return *this = ms;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_slice &operator = (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_slice &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_slice& operator += (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_slice &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_slice& operator -= (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_slice &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_slice& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_slice& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_slice &ms) const {
+            return (*this).data_.same_closure (ms.data_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const matrix_slice &ms) const {
+            return (*this).data_ == ms.data_ && s1_ == ms.s1_ && s2_ == ms.s2_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (matrix_slice ms) {
+            if (this != &ms) {
+                BOOST_UBLAS_CHECK (size1 () == ms.size1 (), bad_size ());
+                BOOST_UBLAS_CHECK (size2 () == ms.size2 (), bad_size ());
+                matrix_swap<scalar_swap> (*this, ms);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (matrix_slice ms1, matrix_slice ms2) {
+            ms1.swap (ms2);
+        }
+
+        // Iterator types
+    private:
+        // Use slice as an index - FIXME this fails for packed assignment
+        typedef typename slice_type::const_iterator const_subiterator1_type;
+        typedef typename slice_type::const_iterator subiterator1_type;
+        typedef typename slice_type::const_iterator const_subiterator2_type;
+        typedef typename slice_type::const_iterator subiterator2_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<matrix_slice<matrix_type>,
+                                  typename matrix_type::iterator1::iterator_category> iterator1;
+        typedef indexed_iterator2<matrix_slice<matrix_type>,
+                                  typename matrix_type::iterator2::iterator_category> iterator2;
+        typedef indexed_const_iterator1<matrix_slice<matrix_type>,
+                                        typename matrix_type::const_iterator1::iterator_category> const_iterator1;
+        typedef indexed_const_iterator2<matrix_slice<matrix_type>,
+                                        typename matrix_type::const_iterator2::iterator_category> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, i, j);
+#else
+            return const_iterator1 (*this, s1_.begin () + i, s2_.begin () + j);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int /* rank */, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator1 (*this, i, j);
+#else
+            return iterator1 (*this, s1_.begin () + i, s2_.begin () + j);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, i, j);
+#else
+            return const_iterator2 (*this, s1_.begin () + i, s2_.begin () + j);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int /* rank */, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator2 (*this, i, j);
+#else
+            return iterator2 (*this, s1_.begin () + i, s2_.begin () + j);
+#endif
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<matrix_slice>,
+            public iterator_base_traits<typename M::const_iterator1::iterator_category>::template
+                        iterator_base<const_iterator1, value_type>::type {
+        public:
+            typedef typename M::const_iterator1::value_type value_type;
+            typedef typename M::const_iterator1::difference_type difference_type;
+            typedef typename M::const_reference reference;    //FIXME due to indexing access
+            typedef typename M::const_iterator1::pointer pointer;
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &ms, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (ms), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return const_iterator2 ((*this) (), it1_, it2_ ().begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return const_iterator2 ((*this) (), it1_, it2_ ().end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<matrix_slice>,
+            public iterator_base_traits<typename M::iterator1::iterator_category>::template
+                        iterator_base<iterator1, value_type>::type {
+        public:
+            typedef typename M::iterator1::value_type value_type;
+            typedef typename M::iterator1::difference_type difference_type;
+            typedef typename M::reference reference;    //FIXME due to indexing access
+            typedef typename M::iterator1::pointer pointer;
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &ms, const subiterator1_type &it1, const subiterator2_type &it2):
+                container_reference<self_type> (ms), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                return iterator2 ((*this) (), it1_, it2_ ().begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                return iterator2 ((*this) (), it1_, it2_ ().end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            subiterator1_type it1_;
+            subiterator2_type it2_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1 (), 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<matrix_slice>,
+            public iterator_base_traits<typename M::const_iterator2::iterator_category>::template
+                        iterator_base<const_iterator2, value_type>::type {
+        public:
+            typedef typename M::const_iterator2::value_type value_type;
+            typedef typename M::const_iterator2::difference_type difference_type;
+            typedef typename M::const_reference reference;    //FIXME due to indexing access
+            typedef typename M::const_iterator2::pointer pointer;
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &ms, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (ms), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return const_iterator1 ((*this) (), it1_ ().begin (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return const_iterator1 ((*this) (), it1_ ().end (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<matrix_slice>,
+            public iterator_base_traits<typename M::iterator2::iterator_category>::template
+                        iterator_base<iterator2, value_type>::type {
+        public:
+            typedef typename M::iterator2::value_type value_type;
+            typedef typename M::iterator2::difference_type difference_type;
+            typedef typename M::reference reference;    //FIXME due to indexing access
+            typedef typename M::iterator2::pointer pointer;
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &ms, const subiterator1_type &it1, const subiterator2_type &it2):
+                container_reference<self_type> (ms), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                return iterator1 ((*this) (), it1_ ().begin (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                return iterator1 ((*this) (), it1_ ().end (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            subiterator1_type it1_;
+            subiterator2_type it2_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2 ());
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        slice_type s1_;
+        slice_type s2_;
+    };
+
+    // Simple Projections
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_slice<M> subslice (M &data, typename M::size_type start1, typename M::difference_type stride1, typename M::size_type size1, typename M::size_type start2, typename M::difference_type stride2, typename M::size_type size2) {
+        typedef basic_slice<typename M::size_type, typename M::difference_type> slice_type;
+        return matrix_slice<M> (data, slice_type (start1, stride1, size1), slice_type (start2, stride2, size2));
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_slice<const M> subslice (const M &data, typename M::size_type start1, typename M::difference_type stride1, typename M::size_type size1, typename M::size_type start2, typename M::difference_type stride2, typename M::size_type size2) {
+        typedef basic_slice<typename M::size_type, typename M::difference_type> slice_type;
+        return matrix_slice<const M> (data, slice_type (start1, stride1, size1), slice_type (start2, stride2, size2));
+    }
+
+    // Generic Projections
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_slice<M> project (M &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) {
+        return matrix_slice<M> (data, s1, s2);
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    const matrix_slice<const M> project (const M &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) {
+        // ISSUE was: return matrix_slice<M> (const_cast<M &> (data), s1, s2);
+        return matrix_slice<const M> (data, s1, s2);
+    }
+    // ISSUE in the following two functions it would be logical to use matrix_slice<V>::range_type but this confuses VC7.1 and 8.0
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_slice<M> project (matrix_slice<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
+        return data.project (r1, r2);
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    const matrix_slice<M> project (const matrix_slice<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
+        return data.project (r1, r2);
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    matrix_slice<M> project (matrix_slice<M> &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) {
+        return data.project (s1, s2);
+    }
+    template<class M>
+    BOOST_UBLAS_INLINE
+    const matrix_slice<M> project (const matrix_slice<M> &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) {
+        return data.project (s1, s2);
+    }
+
+    // Specialization of temporary_traits
+    template <class M>
+    struct matrix_temporary_traits< matrix_slice<M> >
+    : matrix_temporary_traits< M > {};
+    template <class M>
+    struct matrix_temporary_traits< const matrix_slice<M> >
+    : matrix_temporary_traits< M > {};
+
+    template <class M>
+    struct vector_temporary_traits< matrix_slice<M> >
+    : vector_temporary_traits< M > {};
+    template <class M>
+    struct vector_temporary_traits< const matrix_slice<M> >
+    : vector_temporary_traits< M > {};
+
+    // Matrix based indirection class
+    // Contributed by Toon Knapen.
+    // Extended and optimized by Kresimir Fresl.
+    /** \brief A matrix referencing a non continuous submatrix of elements given another matrix of indices.
+     *
+     * It is the most general version of any submatrices because it uses another matrix of indices to reference
+     * the submatrix. 
+     *
+     * The matrix of indices can be of any type with the restriction that its elements must be
+     * type-compatible with the size_type \c of the container. In practice, the following are good candidates:
+     * - \c boost::numeric::ublas::indirect_array<A> where \c A can be \c int, \c size_t, \c long, etc...
+     * - \c boost::numeric::ublas::matrix<int> can work too (\c int can be replaced by another integer type)
+     * - etc...
+     *
+     * An indirect matrix can be used as a normal matrix in any expression. If the specified indirect matrix 
+     * falls outside that of the indices of the matrix, then the \c matrix_indirect is not a well formed 
+     * \i Matrix \i Expression and access to an element outside of indices of the matrix is \b undefined.
+     *
+     * \tparam V the type of the referenced matrix, for example \c matrix<double>)
+     * \tparam IA the type of index matrix. Default is \c ublas::indirect_array<>
+     */
+    template<class M, class IA>
+    class matrix_indirect:
+        public matrix_expression<matrix_indirect<M, IA> > {
+
+        typedef matrix_indirect<M, IA> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef M matrix_type;
+        typedef IA indirect_array_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef basic_range<size_type, difference_type> range_type;
+        typedef basic_slice<size_type, difference_type> slice_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        matrix_indirect (matrix_type &data, size_type size1, size_type size2):
+            data_ (data), ia1_ (size1), ia2_ (size2) {}
+        BOOST_UBLAS_INLINE
+        matrix_indirect (matrix_type &data, const indirect_array_type &ia1, const indirect_array_type &ia2):
+            data_ (data), ia1_ (ia1.preprocess (data.size1 ())), ia2_ (ia2.preprocess (data.size2 ())) {}
+        BOOST_UBLAS_INLINE
+        matrix_indirect (const matrix_closure_type &data, const indirect_array_type &ia1, const indirect_array_type &ia2, int):
+            data_ (data), ia1_ (ia1.preprocess (data.size1 ())), ia2_ (ia2.preprocess (data.size2 ())) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return ia1_.size ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return ia2_.size ();
+        }
+        BOOST_UBLAS_INLINE
+        const indirect_array_type &indirect1 () const {
+            return ia1_;
+        }
+        BOOST_UBLAS_INLINE
+        indirect_array_type &indirect1 () {
+            return ia1_;
+        }
+        BOOST_UBLAS_INLINE
+        const indirect_array_type &indirect2 () const {
+            return ia2_;
+        }
+        BOOST_UBLAS_INLINE
+        indirect_array_type &indirect2 () {
+            return ia2_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            return data_ (ia1_ (i), ia2_ (j));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            return data_ (ia1_ (i), ia2_ (j));
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) const {
+            return data_ (ia1_ (i), ia2_ (j));
+        }
+#endif
+
+        // ISSUE can this be done in free project function?
+        // Although a const function can create a non-const proxy to a non-const object
+        // Critical is that matrix_type and data_ (vector_closure_type) are const correct
+        BOOST_UBLAS_INLINE
+        matrix_indirect<matrix_type, indirect_array_type> project (const range_type &r1, const range_type &r2) const {
+            return matrix_indirect<matrix_type, indirect_array_type> (data_, ia1_.compose (r1.preprocess (data_.size1 ())), ia2_.compose (r2.preprocess (data_.size2 ())), 0);
+        }
+        BOOST_UBLAS_INLINE
+        matrix_indirect<matrix_type, indirect_array_type> project (const slice_type &s1, const slice_type &s2) const {
+            return matrix_indirect<matrix_type, indirect_array_type> (data_, ia1_.compose (s1.preprocess (data_.size1 ())), ia2_.compose (s2.preprocess (data_.size2 ())), 0);
+        }
+        BOOST_UBLAS_INLINE
+        matrix_indirect<matrix_type, indirect_array_type> project (const indirect_array_type &ia1, const indirect_array_type &ia2) const {
+            return matrix_indirect<matrix_type, indirect_array_type> (data_, ia1_.compose (ia1.preprocess (data_.size1 ())), ia2_.compose (ia2.preprocess (data_.size2 ())), 0);
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        matrix_indirect &operator = (const matrix_indirect &mi) {
+            matrix_assign<scalar_assign> (*this, mi);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_indirect &assign_temporary (matrix_indirect &mi) {
+            return *this = mi;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_indirect &operator = (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_indirect &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_indirect& operator += (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_indirect &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_indirect& operator -= (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, typename matrix_temporary_traits<M>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        matrix_indirect &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_indirect& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        matrix_indirect& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const matrix_indirect &mi) const {
+            return (*this).data_.same_closure (mi.data_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const matrix_indirect &mi) const {
+            return (*this).data_ == mi.data_ && ia1_ == mi.ia1_ && ia2_ == mi.ia2_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (matrix_indirect mi) {
+            if (this != &mi) {
+                BOOST_UBLAS_CHECK (size1 () == mi.size1 (), bad_size ());
+                BOOST_UBLAS_CHECK (size2 () == mi.size2 (), bad_size ());
+                matrix_swap<scalar_swap> (*this, mi);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (matrix_indirect mi1, matrix_indirect mi2) {
+            mi1.swap (mi2);
+        }
+
+        // Iterator types
+    private:
+        typedef typename IA::const_iterator const_subiterator1_type;
+        typedef typename IA::const_iterator subiterator1_type;
+        typedef typename IA::const_iterator const_subiterator2_type;
+        typedef typename IA::const_iterator subiterator2_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<matrix_indirect<matrix_type, indirect_array_type>,
+                                  typename matrix_type::iterator1::iterator_category> iterator1;
+        typedef indexed_iterator2<matrix_indirect<matrix_type, indirect_array_type>,
+                                  typename matrix_type::iterator2::iterator_category> iterator2;
+        typedef indexed_const_iterator1<matrix_indirect<matrix_type, indirect_array_type>,
+                                        typename matrix_type::const_iterator1::iterator_category> const_iterator1;
+        typedef indexed_const_iterator2<matrix_indirect<matrix_type, indirect_array_type>,
+                                        typename matrix_type::const_iterator2::iterator_category> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator1 (*this, i, j);
+#else
+            return const_iterator1 (*this, ia1_.begin () + i, ia2_.begin () + j);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int /* rank */, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator1 (*this, i, j);
+#else
+            return iterator1 (*this, ia1_.begin () + i, ia2_.begin () + j);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator2 (*this, i, j);
+#else
+            return const_iterator2 (*this, ia1_.begin () + i, ia2_.begin () + j);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int /* rank */, size_type i, size_type j) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator2 (*this, i, j);
+#else
+            return iterator2 (*this, ia1_.begin () + i, ia2_.begin () + j);
+#endif
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<matrix_indirect>,
+            public iterator_base_traits<typename M::const_iterator1::iterator_category>::template
+                        iterator_base<const_iterator1, value_type>::type {
+        public:
+            typedef typename M::const_iterator1::value_type value_type;
+            typedef typename M::const_iterator1::difference_type difference_type;
+            typedef typename M::const_reference reference;    //FIXME due to indexing access
+            typedef typename M::const_iterator1::pointer pointer;
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &mi, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (mi), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return const_iterator2 ((*this) (), it1_, it2_ ().begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return const_iterator2 ((*this) (), it1_, it2_ ().end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<matrix_indirect>,
+            public iterator_base_traits<typename M::iterator1::iterator_category>::template
+                        iterator_base<iterator1, value_type>::type {
+        public:
+            typedef typename M::iterator1::value_type value_type;
+            typedef typename M::iterator1::difference_type difference_type;
+            typedef typename M::reference reference;    //FIXME due to indexing access
+            typedef typename M::iterator1::pointer pointer;
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &mi, const subiterator1_type &it1, const subiterator2_type &it2):
+                container_reference<self_type> (mi), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                return iterator2 ((*this) (), it1_, it2_ ().begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                return iterator2 ((*this) (), it1_, it2_ ().end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            subiterator1_type it1_;
+            subiterator2_type it2_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1 (), 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<matrix_indirect>,
+            public iterator_base_traits<typename M::const_iterator2::iterator_category>::template
+                        iterator_base<const_iterator2, value_type>::type {
+        public:
+            typedef typename M::const_iterator2::value_type value_type;
+            typedef typename M::const_iterator2::difference_type difference_type;
+            typedef typename M::const_reference reference;    //FIXME due to indexing access
+            typedef typename M::const_iterator2::pointer pointer;
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &mi, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (mi), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return const_iterator1 ((*this) (), it1_ ().begin (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return const_iterator1 ((*this) (), it1_ ().end (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<matrix_indirect>,
+            public iterator_base_traits<typename M::iterator2::iterator_category>::template
+                        iterator_base<iterator2, value_type>::type {
+        public:
+            typedef typename M::iterator2::value_type value_type;
+            typedef typename M::iterator2::difference_type difference_type;
+            typedef typename M::reference reference;    //FIXME due to indexing access
+            typedef typename M::iterator2::pointer pointer;
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &mi, const subiterator1_type &it1, const subiterator2_type &it2):
+                container_reference<self_type> (mi), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                // FIXME replace find with at_element
+                return (*this) ().data_ (*it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                return iterator1 ((*this) (), it1_ ().begin (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                return iterator1 ((*this) (), it1_ ().end (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure  (it ()), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            subiterator1_type it1_;
+            subiterator2_type it2_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2 ());
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        indirect_array_type ia1_;
+        indirect_array_type ia2_;
+    };
+
+    // Projections
+    template<class M, class A>
+    BOOST_UBLAS_INLINE
+    matrix_indirect<M, indirect_array<A> > project (M &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
+        return matrix_indirect<M, indirect_array<A> > (data, ia1, ia2);
+    }
+    template<class M, class A>
+    BOOST_UBLAS_INLINE
+    const matrix_indirect<const M, indirect_array<A> > project (const M &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
+        // ISSUE was: return matrix_indirect<M, indirect_array<A> > (const_cast<M &> (data), ia1, ia2);
+        return matrix_indirect<const M, indirect_array<A> > (data, ia1, ia2);
+    }
+    template<class M, class IA>
+    BOOST_UBLAS_INLINE
+    matrix_indirect<M, IA> project (matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::range_type &r1, const typename matrix_indirect<M, IA>::range_type &r2) {
+        return data.project (r1, r2);
+    }
+    template<class M, class IA>
+    BOOST_UBLAS_INLINE
+    const matrix_indirect<M, IA> project (const matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::range_type &r1, const typename matrix_indirect<M, IA>::range_type &r2) {
+        return data.project (r1, r2);
+    }
+    template<class M, class IA>
+    BOOST_UBLAS_INLINE
+    matrix_indirect<M, IA> project (matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::slice_type &s1, const typename matrix_indirect<M, IA>::slice_type &s2) {
+        return data.project (s1, s2);
+    }
+    template<class M, class IA>
+    BOOST_UBLAS_INLINE
+    const matrix_indirect<M, IA> project (const matrix_indirect<M, IA> &data, const typename matrix_indirect<M, IA>::slice_type &s1, const typename matrix_indirect<M, IA>::slice_type &s2) {
+        return data.project (s1, s2);
+    }
+    template<class M, class A>
+    BOOST_UBLAS_INLINE
+    matrix_indirect<M, indirect_array<A> > project (matrix_indirect<M, indirect_array<A> > &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
+        return data.project (ia1, ia2);
+    }
+    template<class M, class A>
+    BOOST_UBLAS_INLINE
+    const matrix_indirect<M, indirect_array<A> > project (const matrix_indirect<M, indirect_array<A> > &data, const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
+        return data.project (ia1, ia2);
+    }
+
+    /// Specialization of temporary_traits
+    template <class M>
+    struct matrix_temporary_traits< matrix_indirect<M> >
+    : matrix_temporary_traits< M > {};
+    template <class M>
+    struct matrix_temporary_traits< const matrix_indirect<M> >
+    : matrix_temporary_traits< M > {};
+
+    template <class M>
+    struct vector_temporary_traits< matrix_indirect<M> >
+    : vector_temporary_traits< M > {};
+    template <class M>
+    struct vector_temporary_traits< const matrix_indirect<M> >
+    : vector_temporary_traits< M > {};
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/matrix_sparse.hpp b/include/boost/numeric/ublas/matrix_sparse.hpp
new file mode 100644
index 0000000..b702743
--- /dev/null
+++ b/include/boost/numeric/ublas/matrix_sparse.hpp
@@ -0,0 +1,5773 @@
+//
+//  Copyright (c) 2000-2007
+//  Joerg Walter, Mathias Koch, Gunter Winkler
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_MATRIX_SPARSE_
+#define _BOOST_UBLAS_MATRIX_SPARSE_
+
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/matrix_expression.hpp>
+#include <boost/numeric/ublas/detail/matrix_assign.hpp>
+#if BOOST_UBLAS_TYPE_CHECK
+#include <boost/numeric/ublas/matrix.hpp>
+#endif
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+
+#ifdef BOOST_UBLAS_STRICT_MATRIX_SPARSE
+
+    template<class M>
+    class sparse_matrix_element:
+       public container_reference<M> {
+    public:
+        typedef M matrix_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+        typedef const value_type &const_reference;
+        typedef value_type *pointer;
+        typedef const value_type *const_pointer;
+
+    private:
+        // Proxied element operations
+        void get_d () const {
+            const_pointer p = (*this) ().find_element (i_, j_);
+            if (p)
+                d_ = *p;
+            else
+                d_ = value_type/*zero*/();
+        }
+
+        void set (const value_type &s) const {
+            pointer p = (*this) ().find_element (i_, j_);
+            if (!p)
+                (*this) ().insert_element (i_, j_, s);
+            else
+                *p = s;
+        }
+        
+    public:
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        sparse_matrix_element (matrix_type &m, size_type i, size_type j):
+            container_reference<matrix_type> (m), i_ (i), j_ (j) {
+        }
+        BOOST_UBLAS_INLINE
+        sparse_matrix_element (const sparse_matrix_element &p):
+            container_reference<matrix_type> (p), i_ (p.i_), j_ (p.j_) {}
+        BOOST_UBLAS_INLINE
+        ~sparse_matrix_element () {
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        sparse_matrix_element &operator = (const sparse_matrix_element &p) {
+            // Overide the implict copy assignment
+            p.get_d ();
+            set (p.d_);
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_matrix_element &operator = (const D &d) {
+            set (d);
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_matrix_element &operator += (const D &d) {
+            get_d ();
+            d_ += d;
+            set (d_);
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_matrix_element &operator -= (const D &d) {
+            get_d ();
+            d_ -= d;
+            set (d_);
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_matrix_element &operator *= (const D &d) {
+            get_d ();
+            d_ *= d;
+            set (d_);
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_matrix_element &operator /= (const D &d) {
+            get_d ();
+            d_ /= d;
+            set (d_);
+            return *this;
+        }
+
+        // Comparison
+        template<class D>
+        BOOST_UBLAS_INLINE
+        bool operator == (const D &d) const {
+            get_d ();
+            return d_ == d;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        bool operator != (const D &d) const {
+            get_d ();
+            return d_ != d;
+        }
+
+        // Conversion - weak link in proxy as d_ is not a perfect alias for the element
+        BOOST_UBLAS_INLINE
+        operator const_reference () const {
+            get_d ();
+            return d_;
+        }
+
+        // Conversion to reference - may be invalidated
+        BOOST_UBLAS_INLINE
+        value_type& ref () const {
+            const pointer p = (*this) ().find_element (i_, j_);
+            if (!p)
+                return (*this) ().insert_element (i_, j_, value_type/*zero*/());
+            else
+                return *p;
+        }
+
+    private:
+        size_type i_;
+        size_type j_;
+        mutable value_type d_;
+    };
+
+    /*
+     * Generalise explicit reference access
+     */
+    namespace detail {
+        template <class V>
+        struct element_reference<sparse_matrix_element<V> > {
+            typedef typename V::value_type& reference;
+            static reference get_reference (const sparse_matrix_element<V>& sve)
+            {
+                return sve.ref ();
+            }
+        };
+    }
+
+
+    template<class M>
+    struct type_traits<sparse_matrix_element<M> > {
+        typedef typename M::value_type element_type;
+        typedef type_traits<sparse_matrix_element<M> > self_type;
+        typedef typename type_traits<element_type>::value_type value_type;
+        typedef typename type_traits<element_type>::const_reference const_reference;
+        typedef sparse_matrix_element<M> reference;
+        typedef typename type_traits<element_type>::real_type real_type;
+        typedef typename type_traits<element_type>::precision_type precision_type;
+
+        static const unsigned plus_complexity = type_traits<element_type>::plus_complexity;
+        static const unsigned multiplies_complexity = type_traits<element_type>::multiplies_complexity;
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type real (const_reference t) {
+            return type_traits<element_type>::real (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type imag (const_reference t) {
+            return type_traits<element_type>::imag (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        value_type conj (const_reference t) {
+            return type_traits<element_type>::conj (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type type_abs (const_reference t) {
+            return type_traits<element_type>::type_abs (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        value_type type_sqrt (const_reference t) {
+            return type_traits<element_type>::type_sqrt (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_1 (const_reference t) {
+            return type_traits<element_type>::norm_1 (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_2 (const_reference t) {
+            return type_traits<element_type>::norm_2 (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_inf (const_reference t) {
+            return type_traits<element_type>::norm_inf (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        bool equals (const_reference t1, const_reference t2) {
+            return type_traits<element_type>::equals (t1, t2);
+        }
+    };
+
+    template<class M1, class T2>
+    struct promote_traits<sparse_matrix_element<M1>, T2> {
+        typedef typename promote_traits<typename sparse_matrix_element<M1>::value_type, T2>::promote_type promote_type;
+    };
+    template<class T1, class M2>
+    struct promote_traits<T1, sparse_matrix_element<M2> > {
+        typedef typename promote_traits<T1, typename sparse_matrix_element<M2>::value_type>::promote_type promote_type;
+    };
+    template<class M1, class M2>
+    struct promote_traits<sparse_matrix_element<M1>, sparse_matrix_element<M2> > {
+        typedef typename promote_traits<typename sparse_matrix_element<M1>::value_type,
+                                        typename sparse_matrix_element<M2>::value_type>::promote_type promote_type;
+    };
+
+#endif
+
+   /** \brief Index map based sparse matrix of values of type \c T
+    *
+    * This class represents a matrix by using a \c key to value mapping. The default type is
+    * \code template<class T, class L = row_major, class A =  map_std<std::size_t, T> > class mapped_matrix; \endcode
+    * So, by default a STL map container is used to associate keys and values. The key is computed depending on 
+    * the layout type \c L as \code key = layout_type::element(i, size1_, j, size2_); \endcode
+    * which means \code key = (i*size2+j) \endcode for a row major matrix.
+    * Limitations: The matrix size must not exceed \f$(size1*size2) < \f$ \code std::limits<std::size_t> \endcode. 
+    * The \ref find1() and \ref find2() operations have a complexity of at least \f$\mathcal{O}(log(nnz))\f$, depending
+    * on the efficiency of \c std::lower_bound on the key set of the map.
+    * Orientation and storage can also be specified, otherwise a row major orientation is used. 
+    * It is \b not required by the storage to initialize elements of the matrix. By default, the orientation is \c row_major. 
+    *
+    * \sa fwd.hpp, storage_sparse.hpp
+    *
+    * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+    * \tparam L the storage organization. It can be either \c row_major or \c column_major. By default it is \c row_major
+    */
+    template<class T, class L, class A>
+    class mapped_matrix:
+        public matrix_container<mapped_matrix<T, L, A> > {
+
+        typedef T &true_reference;
+        typedef T *pointer;
+        typedef const T * const_pointer;
+        typedef L layout_type;
+        typedef mapped_matrix<T, L, A> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef A array_type;
+        typedef const T &const_reference;
+#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE
+        typedef typename detail::map_traits<A, T>::reference reference;
+#else
+        typedef sparse_matrix_element<self_type> reference;
+#endif
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef mapped_vector<T, A> vector_temporary_type;
+        typedef self_type matrix_temporary_type;
+        typedef sparse_tag storage_category;
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        mapped_matrix ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0), data_ () {}
+        BOOST_UBLAS_INLINE
+        mapped_matrix (size_type size1, size_type size2, size_type non_zeros = 0):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), data_ () {
+            detail::map_reserve (data (), restrict_capacity (non_zeros));
+        }
+        BOOST_UBLAS_INLINE
+        mapped_matrix (const mapped_matrix &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_matrix (const matrix_expression<AE> &ae, size_type non_zeros = 0):
+            matrix_container<self_type> (),
+            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ () {
+            detail::map_reserve (data (), restrict_capacity (non_zeros));
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz_capacity () const {
+            return detail::map_capacity (data ());
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz () const {
+            return data (). size ();
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const array_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+        // Resizing
+    private:
+        BOOST_UBLAS_INLINE
+        size_type restrict_capacity (size_type non_zeros) const {
+            // Guarding against overflow - thanks to Alexei Novakov for the hint.
+            // non_zeros = (std::min) (non_zeros, size1_ * size2_);
+            if (size1_ > 0 && non_zeros / size1_ >= size2_)
+                non_zeros = size1_ * size2_;
+            return non_zeros;
+        }
+    public:
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            // FIXME preserve unimplemented
+            BOOST_UBLAS_CHECK (!preserve, internal_logic ());
+            size1_ = size1;
+            size2_ = size2;
+            data ().clear ();
+        }
+
+        // Reserving
+        BOOST_UBLAS_INLINE
+        void reserve (size_type non_zeros, bool preserve = true) {
+            detail::map_reserve (data (), restrict_capacity (non_zeros));
+        }
+
+        // Element support
+        BOOST_UBLAS_INLINE
+        pointer find_element (size_type i, size_type j) {
+            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i, j));
+        }
+        BOOST_UBLAS_INLINE
+        const_pointer find_element (size_type i, size_type j) const {
+            const size_type element = layout_type::element (i, size1_, j, size2_);
+            const_subiterator_type it (data ().find (element));
+            if (it == data ().end ())
+                return 0;
+            BOOST_UBLAS_CHECK ((*it).first == element, internal_logic ());   // broken map
+            return &(*it).second;
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            const size_type element = layout_type::element (i, size1_, j, size2_);
+            const_subiterator_type it (data ().find (element));
+            if (it == data ().end ())
+                return zero_;
+            BOOST_UBLAS_CHECK ((*it).first == element, internal_logic ());   // broken map
+            return (*it).second;
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE
+            const size_type element = layout_type::element (i, size1_, j, size2_);
+            std::pair<subiterator_type, bool> ii (data ().insert (typename array_type::value_type (element, value_type/*zero*/())));
+            BOOST_UBLAS_CHECK ((ii.first)->first == element, internal_logic ());   // broken map
+            return (ii.first)->second;
+#else
+            return reference (*this, i, j);
+#endif
+        }
+
+        // Element assingment
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, size_type j, const_reference t) {
+            BOOST_UBLAS_CHECK (!find_element (i, j), bad_index ());        // duplicate element
+            const size_type element = layout_type::element (i, size1_, j, size2_);
+            std::pair<subiterator_type, bool> ii (data ().insert (typename array_type::value_type (element, t)));
+            BOOST_UBLAS_CHECK ((ii.first)->first == element, internal_logic ());   // broken map
+            if (!ii.second)     // existing element
+                (ii.first)->second = t;
+            return (ii.first)->second;
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i, size_type j) {
+            subiterator_type it = data ().find (layout_type::element (i, size1_, j, size2_));
+            if (it == data ().end ())
+                return;
+            data ().erase (it);
+        }
+        
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            data ().clear ();
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        mapped_matrix &operator = (const mapped_matrix &m) {
+            if (this != &m) {
+                size1_ = m.size1_;
+                size2_ = m.size2_;
+                data () = m.data ();
+            }
+            return *this;
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        mapped_matrix &operator = (const matrix_container<C> &m) {
+            resize (m ().size1 (), m ().size2 (), false);
+            assign (m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        mapped_matrix &assign_temporary (mapped_matrix &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_matrix &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae, detail::map_capacity (data ()));
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_matrix &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_matrix& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae, detail::map_capacity (data ()));
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        mapped_matrix &operator += (const matrix_container<C> &m) {
+            plus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_matrix &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_matrix& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae, detail::map_capacity (data ()));
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        mapped_matrix &operator -= (const matrix_container<C> &m) {
+            minus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_matrix &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        mapped_matrix& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        mapped_matrix& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (mapped_matrix &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                data ().swap (m.data ());
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (mapped_matrix &m1, mapped_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use storage iterator
+        typedef typename A::const_iterator const_subiterator_type;
+        typedef typename A::iterator subiterator_type;
+
+        BOOST_UBLAS_INLINE
+        true_reference at_element (size_type i, size_type j) {
+            const size_type element = layout_type::element (i, size1_, j, size2_);
+            subiterator_type it (data ().find (element));
+            BOOST_UBLAS_CHECK (it != data ().end(), bad_index ());
+            BOOST_UBLAS_CHECK ((*it).first == element, internal_logic ());   // broken map
+            return it->second;
+        }
+
+    public:
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {
+            const_subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));
+            const_subiterator_type it_end (data ().end ());
+            size_type index1 = size_type (-1);
+            size_type index2 = size_type (-1);
+            while (rank == 1 && it != it_end) {
+                index1 = layout_type::index_i ((*it).first, size1_, size2_);
+                index2 = layout_type::index_j ((*it).first, size1_, size2_);
+                if (direction > 0) {
+                    if ((index1 >= i && index2 == j) || (i >= size1_))
+                        break;
+                    ++ i;
+                } else /* if (direction < 0) */ {
+                    if ((index1 <= i && index2 == j) || (i == 0))
+                        break;
+                    -- i;
+                }
+                it = data ().lower_bound (layout_type::address (i, size1_, j, size2_));
+            }
+            if (rank == 1 && index2 != j) {
+                if (direction > 0)
+                    i = size1_;
+                else /* if (direction < 0) */
+                    i = 0;
+                rank = 0;
+            }
+            return const_iterator1 (*this, rank, i, j, it);
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {
+            subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));
+            subiterator_type it_end (data ().end ());
+            size_type index1 = size_type (-1);
+            size_type index2 = size_type (-1);
+            while (rank == 1 && it != it_end) {
+                index1 = layout_type::index_i ((*it).first, size1_, size2_);
+                index2 = layout_type::index_j ((*it).first, size1_, size2_);
+                if (direction > 0) {
+                    if ((index1 >= i && index2 == j) || (i >= size1_))
+                        break;
+                    ++ i;
+                } else /* if (direction < 0) */ {
+                    if ((index1 <= i && index2 == j) || (i == 0))
+                        break;
+                    -- i;
+                }
+                it = data ().lower_bound (layout_type::address (i, size1_, j, size2_));
+            }
+            if (rank == 1 && index2 != j) {
+                if (direction > 0)
+                    i = size1_;
+                else /* if (direction < 0) */
+                    i = 0;
+                rank = 0;
+            }
+            return iterator1 (*this, rank, i, j, it);
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {
+            const_subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));
+            const_subiterator_type it_end (data ().end ());
+            size_type index1 = size_type (-1);
+            size_type index2 = size_type (-1);
+            while (rank == 1 && it != it_end) {
+                index1 = layout_type::index_i ((*it).first, size1_, size2_);
+                index2 = layout_type::index_j ((*it).first, size1_, size2_);
+                if (direction > 0) {
+                    if ((index2 >= j && index1 == i) || (j >= size2_))
+                        break;
+                    ++ j;
+                } else /* if (direction < 0) */ {
+                    if ((index2 <= j && index1 == i) || (j == 0))
+                        break;
+                    -- j;
+                }
+                it = data ().lower_bound (layout_type::address (i, size1_, j, size2_));
+            }
+            if (rank == 1 && index1 != i) {
+                if (direction > 0)
+                    j = size2_;
+                else /* if (direction < 0) */
+                    j = 0;
+                rank = 0;
+            }
+            return const_iterator2 (*this, rank, i, j, it);
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {
+            subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));
+            subiterator_type it_end (data ().end ());
+            size_type index1 = size_type (-1);
+            size_type index2 = size_type (-1);
+            while (rank == 1 && it != it_end) {
+                index1 = layout_type::index_i ((*it).first, size1_, size2_);
+                index2 = layout_type::index_j ((*it).first, size1_, size2_);
+                if (direction > 0) {
+                    if ((index2 >= j && index1 == i) || (j >= size2_))
+                        break;
+                    ++ j;
+                } else /* if (direction < 0) */ {
+                    if ((index2 <= j && index1 == i) || (j == 0))
+                        break;
+                    -- j;
+                }
+                it = data ().lower_bound (layout_type::address (i, size1_, j, size2_));
+            }
+            if (rank == 1 && index1 != i) {
+                if (direction > 0)
+                    j = size2_;
+                else /* if (direction < 0) */
+                    j = 0;
+                rank = 0;
+            }
+            return iterator2 (*this, rank, i, j, it);
+        }
+
+
+        class const_iterator1:
+            public container_const_reference<mapped_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename mapped_matrix::value_type value_type;
+            typedef typename mapped_matrix::difference_type difference_type;
+            typedef typename mapped_matrix::const_reference reference;
+            typedef const typename mapped_matrix::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, int rank, size_type i, size_type j, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    ++ it_;
+                else
+                    *this = (*this) ().find1 (rank_, index1 () + 1, j_, 1);
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    -- it_;
+                else
+                    *this = (*this) ().find1 (rank_, index1 () - 1, j_, -1);
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*it_).second;
+                } else {
+                    return (*this) () (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    const self_type &m = (*this) ();
+                    BOOST_UBLAS_CHECK (layout_type::index_i ((*it_).first, m.size1 (), m.size2 ()) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_i ((*it_).first, m.size1 (), m.size2 ());
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                if (rank_ == 1) {
+                    const self_type &m = (*this) ();
+                    BOOST_UBLAS_CHECK (layout_type::index_j ((*it_).first, m.size1 (), m.size2 ()) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_j ((*it_).first, m.size1 (), m.size2 ());
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+        class iterator1:
+            public container_reference<mapped_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename mapped_matrix::value_type value_type;
+            typedef typename mapped_matrix::difference_type difference_type;
+            typedef typename mapped_matrix::true_reference reference;
+            typedef typename mapped_matrix::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), rank_ (), i_ (), j_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, int rank, size_type i, size_type j, const subiterator_type &it):
+                container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    ++ it_;
+                else
+                    *this = (*this) ().find1 (rank_, index1 () + 1, j_, 1);
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    -- it_;
+                else
+                    *this = (*this) ().find1 (rank_, index1 () - 1, j_, -1);
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*it_).second;
+                } else {
+                    return (*this) ().at_element (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    const self_type &m = (*this) ();
+                    BOOST_UBLAS_CHECK (layout_type::index_i ((*it_).first, m.size1 (), m.size2 ()) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_i ((*it_).first, m.size1 (), m.size2 ());
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                if (rank_ == 1) {
+                    const self_type &m = (*this) ();
+                    BOOST_UBLAS_CHECK (layout_type::index_j ((*it_).first, m.size1 (), m.size2 ()) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_j ((*it_).first, m.size1 (), m.size2 ());
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            subiterator_type it_;
+
+            friend class const_iterator1;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1_, 0);
+        }
+
+        class const_iterator2:
+            public container_const_reference<mapped_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename mapped_matrix::value_type value_type;
+            typedef typename mapped_matrix::difference_type difference_type;
+            typedef typename mapped_matrix::const_reference reference;
+            typedef const typename mapped_matrix::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, int rank, size_type i, size_type j, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    ++ it_;
+                else
+                    *this = (*this) ().find2 (rank_, i_, index2 () + 1, 1);
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    -- it_;
+                else
+                    *this = (*this) ().find2 (rank_, i_, index2 () - 1, -1);
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*it_).second;
+                } else {
+                    return (*this) () (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                if (rank_ == 1) {
+                    const self_type &m = (*this) ();
+                    BOOST_UBLAS_CHECK (layout_type::index_i ((*it_).first, m.size1 (), m.size2 ()) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_i ((*it_).first, m.size1 (), m.size2 ());
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    const self_type &m = (*this) ();
+                    BOOST_UBLAS_CHECK (layout_type::index_j ((*it_).first, m.size1 (), m.size2 ()) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_j ((*it_).first, m.size1 (), m.size2 ());
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        class iterator2:
+            public container_reference<mapped_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename mapped_matrix::value_type value_type;
+            typedef typename mapped_matrix::difference_type difference_type;
+            typedef typename mapped_matrix::true_reference reference;
+            typedef typename mapped_matrix::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), rank_ (), i_ (), j_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, int rank, size_type i, size_type j, const subiterator_type &it):
+                container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    ++ it_;
+                else
+                    *this = (*this) ().find2 (rank_, i_, index2 () + 1, 1);
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    -- it_;
+                else
+                    *this = (*this) ().find2 (rank_, i_, index2 () - 1, -1);
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*it_).second;
+                } else {
+                    return (*this) ().at_element (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                if (rank_ == 1) {
+                    const self_type &m = (*this) ();
+                    BOOST_UBLAS_CHECK (layout_type::index_i ((*it_).first, m.size1 (), m.size2 ()) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_i ((*it_).first, m.size1 (), m.size2 ());
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    const self_type &m = (*this) ();
+                    BOOST_UBLAS_CHECK (layout_type::index_j ((*it_).first, m.size1 (), m.size2 ()) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_j ((*it_).first, m.size1 (), m.size2 ());
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            subiterator_type it_;
+
+            friend class const_iterator2;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+            ar & serialization::make_nvp("size1",s1);
+            ar & serialization::make_nvp("size2",s2);
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+            }
+            ar & serialization::make_nvp("data", data_);
+        }
+
+    private:
+        size_type size1_;
+        size_type size2_;
+        array_type data_;
+        static const value_type zero_;
+    };
+
+    template<class T, class L, class A>
+    const typename mapped_matrix<T, L, A>::value_type mapped_matrix<T, L, A>::zero_ = value_type/*zero*/();
+
+
+    // Vector index map based sparse matrix class
+    template<class T, class L, class A>
+    class mapped_vector_of_mapped_vector:
+        public matrix_container<mapped_vector_of_mapped_vector<T, L, A> > {
+
+        typedef T &true_reference;
+        typedef T *pointer;
+        typedef const T *const_pointer;
+        typedef A array_type;
+        typedef const A const_array_type;
+        typedef L layout_type;
+        typedef mapped_vector_of_mapped_vector<T, L, A> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE
+        typedef typename detail::map_traits<typename A::data_value_type, T>::reference reference;
+#else
+        typedef sparse_matrix_element<self_type> reference;
+#endif
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef mapped_vector<T> vector_temporary_type;
+        typedef self_type matrix_temporary_type;
+        typedef typename A::value_type::second_type vector_data_value_type;
+        typedef sparse_tag storage_category;
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0), data_ () {
+            data_ [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();
+        }
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector (size_type size1, size_type size2, size_type non_zeros = 0):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), data_ () {
+            data_ [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();
+        }
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector (const mapped_vector_of_mapped_vector &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector (const matrix_expression<AE> &ae, size_type non_zeros = 0):
+            matrix_container<self_type> (),
+            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ () {
+            data_ [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz_capacity () const {
+            size_type non_zeros = 0;
+            for (vector_const_subiterator_type itv = data_ ().begin (); itv != data_ ().end (); ++ itv)
+                non_zeros += detail::map_capacity (*itv);
+            return non_zeros;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz () const {
+            size_type filled = 0;
+            for (vector_const_subiterator_type itv = data_ ().begin (); itv != data_ ().end (); ++ itv)
+                filled += (*itv).size ();
+            return filled;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const_array_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            // FIXME preserve unimplemented
+            BOOST_UBLAS_CHECK (!preserve, internal_logic ());
+            size1_ = size1;
+            size2_ = size2;
+            data ().clear ();
+            data () [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();
+        }
+
+        // Element support
+        BOOST_UBLAS_INLINE
+        pointer find_element (size_type i, size_type j) {
+            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i, j));
+        }
+        BOOST_UBLAS_INLINE
+        const_pointer find_element (size_type i, size_type j) const {
+            const size_type element1 = layout_type::index_M (i, j);
+            const size_type element2 = layout_type::index_m (i, j);
+            vector_const_subiterator_type itv (data ().find (element1));
+            if (itv == data ().end ())
+                return 0;
+            BOOST_UBLAS_CHECK ((*itv).first == element1, internal_logic ());   // broken map
+            const_subiterator_type it ((*itv).second.find (element2));
+            if (it == (*itv).second.end ())
+                return 0;
+            BOOST_UBLAS_CHECK ((*it).first == element2, internal_logic ());   // broken map
+            return &(*it).second;
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            const size_type element1 = layout_type::index_M (i, j);
+            const size_type element2 = layout_type::index_m (i, j);
+            vector_const_subiterator_type itv (data ().find (element1));
+            if (itv == data ().end ())
+                return zero_;
+            BOOST_UBLAS_CHECK ((*itv).first == element1, internal_logic ());   // broken map
+            const_subiterator_type it ((*itv).second.find (element2));
+            if (it == (*itv).second.end ())
+                return zero_;
+            BOOST_UBLAS_CHECK ((*itv).first == element1, internal_logic ());   // broken map
+            return (*it).second;
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE
+            const size_type element1 = layout_type::index_M (i, j);
+            const size_type element2 = layout_type::index_m (i, j);
+            vector_data_value_type& vd (data () [element1]);
+            std::pair<subiterator_type, bool> ii (vd.insert (typename array_type::value_type::second_type::value_type (element2, value_type/*zero*/())));
+            BOOST_UBLAS_CHECK ((ii.first)->first == element2, internal_logic ());   // broken map
+            return (ii.first)->second;
+#else
+            return reference (*this, i, j);
+#endif
+        }
+
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, size_type j, const_reference t) {
+            BOOST_UBLAS_CHECK (!find_element (i, j), bad_index ());        // duplicate element
+            const size_type element1 = layout_type::index_M (i, j);
+            const size_type element2 = layout_type::index_m (i, j);
+
+            vector_data_value_type& vd (data () [element1]);
+            std::pair<subiterator_type, bool> ii (vd.insert (typename vector_data_value_type::value_type (element2, t)));
+            BOOST_UBLAS_CHECK ((ii.first)->first == element2, internal_logic ());   // broken map
+            if (!ii.second)     // existing element
+                (ii.first)->second = t;
+            return (ii.first)->second;
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i, size_type j) {
+            vector_subiterator_type itv (data ().find (layout_type::index_M (i, j)));
+            if (itv == data ().end ())
+                return;
+            subiterator_type it ((*itv).second.find (layout_type::index_m (i, j)));
+            if (it == (*itv).second.end ())
+                return;
+            (*itv).second.erase (it);
+        }
+        
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            data ().clear ();
+            data_ [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector &operator = (const mapped_vector_of_mapped_vector &m) {
+            if (this != &m) {
+                size1_ = m.size1_;
+                size2_ = m.size2_;
+                data () = m.data ();
+            }
+            return *this;
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector &operator = (const matrix_container<C> &m) {
+            resize (m ().size1 (), m ().size2 (), false);
+            assign (m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector &assign_temporary (mapped_vector_of_mapped_vector &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector &operator += (const matrix_container<C> &m) {
+            plus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector &operator -= (const matrix_container<C> &m) {
+            minus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        mapped_vector_of_mapped_vector& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (mapped_vector_of_mapped_vector &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                data ().swap (m.data ());
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (mapped_vector_of_mapped_vector &m1, mapped_vector_of_mapped_vector &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use storage iterators
+        typedef typename A::const_iterator vector_const_subiterator_type;
+        typedef typename A::iterator vector_subiterator_type;
+        typedef typename A::value_type::second_type::const_iterator const_subiterator_type;
+        typedef typename A::value_type::second_type::iterator subiterator_type;
+
+        BOOST_UBLAS_INLINE
+        true_reference at_element (size_type i, size_type j) {
+            const size_type element1 = layout_type::index_M (i, j);
+            const size_type element2 = layout_type::index_m (i, j);
+            vector_subiterator_type itv (data ().find (element1));
+            BOOST_UBLAS_CHECK (itv != data ().end(), bad_index ());
+            BOOST_UBLAS_CHECK ((*itv).first == element1, internal_logic ());   // broken map
+            subiterator_type it ((*itv).second.find (element2));
+            BOOST_UBLAS_CHECK (it != (*itv).second.end (), bad_index ());
+            BOOST_UBLAS_CHECK ((*it).first == element2, internal_logic ());    // broken map
+            
+            return it->second;
+        }
+
+    public:
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {
+            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());
+            for (;;) {
+                vector_const_subiterator_type itv (data ().lower_bound (layout_type::index_M (i, j)));
+                vector_const_subiterator_type itv_end (data ().end ());
+                if (itv == itv_end)
+                    return const_iterator1 (*this, rank, i, j, itv_end, (*(-- itv)).second.end ());
+
+                const_subiterator_type it ((*itv).second.lower_bound (layout_type::index_m (i, j)));
+                const_subiterator_type it_end ((*itv).second.end ());
+                if (rank == 0) {
+                    // advance to the first available major index
+                    size_type M = itv->first;
+                    size_type m;
+                    if (it != it_end) { 
+                        m = it->first; 
+                    } else {
+                        m = layout_type::size_m(size1_, size2_);
+                    }
+                    size_type first_i = layout_type::index_M(M,m);
+                    return const_iterator1 (*this, rank, first_i, j, itv, it);
+                }
+                if (it != it_end && (*it).first == layout_type::index_m (i, j))
+                    return const_iterator1 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_i ()) {
+                        if (it == it_end)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        i = (*it).first;
+                    } else {
+                        if (i >= size1_)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        ++ i;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_i ()) {
+                        if (it == (*itv).second.begin ())
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        -- it;
+                        i = (*it).first;
+                    } else {
+                        if (i == 0)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        -- i;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {
+            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());
+            for (;;) {
+                vector_subiterator_type itv (data ().lower_bound (layout_type::index_M (i, j)));
+                vector_subiterator_type itv_end (data ().end ());
+                if (itv == itv_end)
+                    return iterator1 (*this, rank, i, j, itv_end, (*(-- itv)).second.end ());
+
+                subiterator_type it ((*itv).second.lower_bound (layout_type::index_m (i, j)));
+                subiterator_type it_end ((*itv).second.end ());
+                if (rank == 0) {
+                    // advance to the first available major index
+                    size_type M = itv->first;
+                    size_type m;
+                    if (it != it_end) { 
+                        m = it->first; 
+                    } else {
+                        m = layout_type::size_m(size1_, size2_);
+                    }
+                    size_type first_i = layout_type::index_M(M,m);
+                    return iterator1 (*this, rank, first_i, j, itv, it);
+                }
+                if (it != it_end && (*it).first == layout_type::index_m (i, j))
+                    return iterator1 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_i ()) {
+                        if (it == it_end)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        i = (*it).first;
+                    } else {
+                        if (i >= size1_)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        ++ i;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_i ()) {
+                        if (it == (*itv).second.begin ())
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        -- it;
+                        i = (*it).first;
+                    } else {
+                        if (i == 0)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        -- i;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {
+            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());
+            for (;;) {
+                vector_const_subiterator_type itv (data ().lower_bound (layout_type::index_M (i, j)));
+                vector_const_subiterator_type itv_end (data ().end ());
+                if (itv == itv_end)
+                    return const_iterator2 (*this, rank, i, j, itv_end, (*(-- itv)).second.end ());
+
+                const_subiterator_type it ((*itv).second.lower_bound (layout_type::index_m (i, j)));
+                const_subiterator_type it_end ((*itv).second.end ());
+                if (rank == 0) {
+                    // advance to the first available major index
+                    size_type M = itv->first;
+                    size_type m;
+                    if (it != it_end) { 
+                        m = it->first; 
+                    } else {
+                        m = layout_type::size_m(size1_, size2_);
+                    }
+                    size_type first_j = layout_type::index_m(M,m);
+                    return const_iterator2 (*this, rank, i, first_j, itv, it);
+                }
+                if (it != it_end && (*it).first == layout_type::index_m (i, j))
+                    return const_iterator2 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_j ()) {
+                        if (it == it_end)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        j = (*it).first;
+                    } else {
+                        if (j >= size2_)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        ++ j;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_j ()) {
+                        if (it == (*itv).second.begin ())
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        -- it;
+                        j = (*it).first;
+                    } else {
+                        if (j == 0)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        -- j;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {
+            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());
+            for (;;) {
+                vector_subiterator_type itv (data ().lower_bound (layout_type::index_M (i, j)));
+                vector_subiterator_type itv_end (data ().end ());
+                if (itv == itv_end)
+                    return iterator2 (*this, rank, i, j, itv_end, (*(-- itv)).second.end ());
+
+                subiterator_type it ((*itv).second.lower_bound (layout_type::index_m (i, j)));
+                subiterator_type it_end ((*itv).second.end ());
+                if (rank == 0) {
+                    // advance to the first available major index
+                    size_type M = itv->first;
+                    size_type m;
+                    if (it != it_end) { 
+                        m = it->first; 
+                    } else {
+                        m = layout_type::size_m(size1_, size2_);
+                    }
+                    size_type first_j = layout_type::index_m(M,m);
+                    return iterator2 (*this, rank, i, first_j, itv, it);
+                }
+                if (it != it_end && (*it).first == layout_type::index_m (i, j))
+                    return iterator2 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_j ()) {
+                        if (it == it_end)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        j = (*it).first;
+                    } else {
+                        if (j >= size2_)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        ++ j;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_j ()) {
+                        if (it == (*itv).second.begin ())
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        -- it;
+                        j = (*it).first;
+                    } else {
+                        if (j == 0)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        -- j;
+                    }
+                }
+            }
+        }
+
+        class const_iterator1:
+            public container_const_reference<mapped_vector_of_mapped_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename mapped_vector_of_mapped_vector::value_type value_type;
+            typedef typename mapped_vector_of_mapped_vector::difference_type difference_type;
+            typedef typename mapped_vector_of_mapped_vector::const_reference reference;
+            typedef const typename mapped_vector_of_mapped_vector::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, int rank, size_type i, size_type j, const vector_const_subiterator_type &itv, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    ++ it_;
+                else {
+                    const self_type &m = (*this) ();
+                    if (rank_ == 0) {
+                        ++ itv_;
+                        i_ = itv_->first;
+                    } else {
+                        i_ = index1 () + 1;
+                    }
+                    if (rank_ == 1 && ++ itv_ == m.end1 ().itv_)
+                        *this = m.find1 (rank_, i_, j_, 1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).second.begin ();
+                        if (it_ == (*itv_).second.end () || index2 () != j_)
+                            *this = m.find1 (rank_, i_, j_, 1);
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    -- it_;
+                else {
+                    const self_type &m = (*this) ();
+                    if (rank_ == 0) {
+                        -- itv_;
+                        i_ = itv_->first;
+                    } else {
+                        i_ = index1 () - 1;
+                    }
+                    // FIXME: this expression should never become true!
+                    if (rank_ == 1 && -- itv_ == m.end1 ().itv_)
+                        *this = m.find1 (rank_, i_, j_, -1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).second.begin ();
+                        if (it_ == (*itv_).second.end () || index2 () != j_)
+                            *this = m.find1 (rank_, i_, j_, -1);
+                    }
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*it_).second;
+                } else {
+                    return (*this) () (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M ((*itv_).first, (*it_).first) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M ((*itv_).first, (*it_).first);
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m ((*itv_).first, (*it_).first) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m ((*itv_).first, (*it_).first);
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_const_subiterator_type itv_;
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+        class iterator1:
+            public container_reference<mapped_vector_of_mapped_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename mapped_vector_of_mapped_vector::value_type value_type;
+            typedef typename mapped_vector_of_mapped_vector::difference_type difference_type;
+            typedef typename mapped_vector_of_mapped_vector::true_reference reference;
+            typedef typename mapped_vector_of_mapped_vector::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it):
+                container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    ++ it_;
+                else {
+                    self_type &m = (*this) ();
+                    if (rank_ == 0) {
+                        ++ itv_;
+                        i_ = itv_->first;
+                    } else {
+                        i_ = index1 () + 1;
+                    }
+                    if (rank_ == 1 && ++ itv_ == m.end1 ().itv_)
+                        *this = m.find1 (rank_, i_, j_, 1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).second.begin ();
+                        if (it_ == (*itv_).second.end () || index2 () != j_)
+                            *this = m.find1 (rank_, i_, j_, 1);
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    -- it_;
+                else {
+                    self_type &m = (*this) ();
+                    if (rank_ == 0) {
+                        -- itv_;
+                        i_ = itv_->first;
+                    } else {
+                        i_ = index1 () - 1;
+                    }
+                    // FIXME: this expression should never become true!
+                    if (rank_ == 1 && -- itv_ == m.end1 ().itv_)
+                        *this = m.find1 (rank_, i_, j_, -1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).second.begin ();
+                        if (it_ == (*itv_).second.end () || index2 () != j_)
+                            *this = m.find1 (rank_, i_, j_, -1);
+                    }
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*it_).second;
+                } else {
+                    return (*this) ().at_element (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M ((*itv_).first, (*it_).first) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M ((*itv_).first, (*it_).first);
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m ((*itv_).first, (*it_).first) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m ((*itv_).first, (*it_).first);
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_subiterator_type itv_;
+            subiterator_type it_;
+
+            friend class const_iterator1;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1_, 0);
+        }
+
+        class const_iterator2:
+            public container_const_reference<mapped_vector_of_mapped_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename mapped_vector_of_mapped_vector::value_type value_type;
+            typedef typename mapped_vector_of_mapped_vector::difference_type difference_type;
+            typedef typename mapped_vector_of_mapped_vector::const_reference reference;
+            typedef const typename mapped_vector_of_mapped_vector::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, int rank, size_type i, size_type j, const vector_const_subiterator_type &itv, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    ++ it_;
+                else {
+                    const self_type &m = (*this) ();
+                    if (rank_ == 0) {
+                        ++ itv_;
+                        j_ = itv_->first;
+                    } else {
+                        j_ = index2 () + 1;
+                    }
+                    if (rank_ == 1 && ++ itv_ == m.end2 ().itv_)
+                        *this = m.find2 (rank_, i_, j_, 1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).second.begin ();
+                        if (it_ == (*itv_).second.end () || index1 () != i_)
+                            *this = m.find2 (rank_, i_, j_, 1);
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    -- it_;
+                else {
+                    const self_type &m = (*this) ();
+                    if (rank_ == 0) {
+                        -- itv_;
+                        j_ = itv_->first;
+                    } else {
+                        j_ = index2 () - 1;
+                    }
+                    // FIXME: this expression should never become true!
+                    if (rank_ == 1 && -- itv_ == m.end2 ().itv_)
+                        *this = m.find2 (rank_, i_, j_, -1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).second.begin ();
+                        if (it_ == (*itv_).second.end () || index1 () != i_)
+                            *this = m.find2 (rank_, i_, j_, -1);
+                    }
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*it_).second;
+                } else {
+                    return (*this) () (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M ((*itv_).first, (*it_).first) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M ((*itv_).first, (*it_).first);
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m ((*itv_).first, (*it_).first) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m ((*itv_).first, (*it_).first);
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_const_subiterator_type itv_;
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        class iterator2:
+            public container_reference<mapped_vector_of_mapped_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename mapped_vector_of_mapped_vector::value_type value_type;
+            typedef typename mapped_vector_of_mapped_vector::difference_type difference_type;
+            typedef typename mapped_vector_of_mapped_vector::true_reference reference;
+            typedef typename mapped_vector_of_mapped_vector::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it):
+                container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    ++ it_;
+                else {
+                    self_type &m = (*this) ();
+                    if (rank_ == 0) {
+                        ++ itv_;
+                        j_ = itv_->first;
+                    } else {
+                        j_ = index2 () + 1;
+                    }
+                    if (rank_ == 1 && ++ itv_ == m.end2 ().itv_)
+                        *this = m.find2 (rank_, i_, j_, 1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).second.begin ();
+                        if (it_ == (*itv_).second.end () || index1 () != i_)
+                            *this = m.find2 (rank_, i_, j_, 1);
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    -- it_;
+                else {
+                    self_type &m = (*this) ();
+                    if (rank_ == 0) {
+                        -- itv_;
+                        j_ = itv_->first;
+                    } else {
+                        j_ = index2 () - 1;
+                    }
+                    // FIXME: this expression should never become true!
+                    if (rank_ == 1 && -- itv_ == m.end2 ().itv_)
+                        *this = m.find2 (rank_, i_, j_, -1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).second.begin ();
+                        if (it_ == (*itv_).second.end () || index1 () != i_)
+                            *this = m.find2 (rank_, i_, j_, -1);
+                    }
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*it_).second;
+                } else {
+                    return (*this) ().at_element (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M ((*itv_).first, (*it_).first) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M ((*itv_).first, (*it_).first);
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m ((*itv_).first, (*it_).first) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m ((*itv_).first, (*it_).first);
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_subiterator_type itv_;
+            subiterator_type it_;
+
+            friend class const_iterator2;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+            ar & serialization::make_nvp("size1",s1);
+            ar & serialization::make_nvp("size2",s2);
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+            }
+            ar & serialization::make_nvp("data", data_);
+        }
+
+    private:
+        size_type size1_;
+        size_type size2_;
+        array_type data_;
+        static const value_type zero_;
+    };
+
+    template<class T, class L, class A>
+    const typename mapped_vector_of_mapped_vector<T, L, A>::value_type mapped_vector_of_mapped_vector<T, L, A>::zero_ = value_type/*zero*/();
+
+
+    // Comperssed array based sparse matrix class
+    // Thanks to Kresimir Fresl for extending this to cover different index bases.
+    template<class T, class L, std::size_t IB, class IA, class TA>
+    class compressed_matrix:
+        public matrix_container<compressed_matrix<T, L, IB, IA, TA> > {
+
+        typedef T &true_reference;
+        typedef T *pointer;
+        typedef const T *const_pointer;
+        typedef L layout_type;
+        typedef compressed_matrix<T, L, IB, IA, TA> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        // ISSUE require type consistency check
+        // is_convertable (IA::size_type, TA::size_type)
+        typedef typename IA::value_type size_type;
+        // size_type for the data arrays.
+        typedef typename IA::size_type array_size_type;
+        // FIXME difference type for sparse storage iterators should it be in the container?
+        typedef typename IA::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE
+        typedef T &reference;
+#else
+        typedef sparse_matrix_element<self_type> reference;
+#endif
+        typedef IA index_array_type;
+        typedef TA value_array_type;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef compressed_vector<T, IB, IA, TA> vector_temporary_type;
+        typedef self_type matrix_temporary_type;
+        typedef sparse_tag storage_category;
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        compressed_matrix ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0), capacity_ (restrict_capacity (0)),
+            filled1_ (1), filled2_ (0),
+            index1_data_ (layout_type::size_M (size1_, size2_) + 1), index2_data_ (capacity_), value_data_ (capacity_) {
+            index1_data_ [filled1_ - 1] = k_based (filled2_);
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        compressed_matrix (size_type size1, size_type size2, size_type non_zeros = 0):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), capacity_ (restrict_capacity (non_zeros)),
+            filled1_ (1), filled2_ (0),
+            index1_data_ (layout_type::size_M (size1_, size2_) + 1), index2_data_ (capacity_), value_data_ (capacity_) {
+            index1_data_ [filled1_ - 1] = k_based (filled2_);
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        compressed_matrix (const compressed_matrix &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_), capacity_ (m.capacity_),
+            filled1_ (m.filled1_), filled2_ (m.filled2_),
+            index1_data_ (m.index1_data_), index2_data_ (m.index2_data_), value_data_ (m.value_data_) {
+            storage_invariants ();
+        }
+         
+        BOOST_UBLAS_INLINE
+        compressed_matrix (const coordinate_matrix<T, L, IB, IA, TA> &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1()), size2_ (m.size2()),
+            index1_data_ (layout_type::size_M (size1_, size2_) + 1)
+        {
+            m.sort();
+            reserve(m.nnz(), false);
+            filled2_ = m.nnz();
+            const_subiterator_type  i_start = m.index1_data().begin();
+            const_subiterator_type  i_end   = (i_start + filled2_);
+            const_subiterator_type  i = i_start;
+            size_type r = 1;
+            for (; (r < layout_type::size_M (size1_, size2_)) && (i != i_end); ++r) {
+                i = std::lower_bound(i, i_end, r);
+                index1_data_[r] = k_based( i - i_start );
+            }
+            filled1_ = r + 1;
+            std::copy( m.index2_data().begin(), m.index2_data().begin() + filled2_, index2_data_.begin());
+            std::copy( m.value_data().begin(), m.value_data().begin() + filled2_, value_data_.begin());
+            index1_data_ [filled1_ - 1] = k_based(filled2_);
+            storage_invariants ();
+        }
+
+       template<class AE>
+       BOOST_UBLAS_INLINE
+       compressed_matrix (const matrix_expression<AE> &ae, size_type non_zeros = 0):
+            matrix_container<self_type> (),
+            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), capacity_ (restrict_capacity (non_zeros)),
+            filled1_ (1), filled2_ (0),
+            index1_data_ (layout_type::size_M (ae ().size1 (), ae ().size2 ()) + 1),
+            index2_data_ (capacity_), value_data_ (capacity_) {
+            index1_data_ [filled1_ - 1] = k_based (filled2_);
+            storage_invariants ();
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz_capacity () const {
+            return capacity_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz () const {
+            return filled2_;
+        }
+        
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        static size_type index_base () {
+            return IB;
+        }
+        BOOST_UBLAS_INLINE
+        array_size_type filled1 () const {
+            return filled1_;
+        }
+        BOOST_UBLAS_INLINE
+        array_size_type filled2 () const {
+            return filled2_;
+        }
+        BOOST_UBLAS_INLINE
+        const index_array_type &index1_data () const {
+            return index1_data_;
+        }
+        BOOST_UBLAS_INLINE
+        const index_array_type &index2_data () const {
+            return index2_data_;
+        }
+        BOOST_UBLAS_INLINE
+        const value_array_type &value_data () const {
+            return value_data_;
+        }
+        BOOST_UBLAS_INLINE
+        void set_filled (const array_size_type& filled1, const array_size_type& filled2) {
+            filled1_ = filled1;
+            filled2_ = filled2;
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        index_array_type &index1_data () {
+            return index1_data_;
+        }
+        BOOST_UBLAS_INLINE
+        index_array_type &index2_data () {
+            return index2_data_;
+        }
+        BOOST_UBLAS_INLINE
+        value_array_type &value_data () {
+            return value_data_;
+        }
+        BOOST_UBLAS_INLINE
+        void complete_index1_data () {
+            while (filled1_ <= layout_type::size_M (size1_, size2_)) {
+                this->index1_data_ [filled1_] = k_based (filled2_);
+                ++ this->filled1_;
+            }
+        }
+
+        // Resizing
+    private:
+        BOOST_UBLAS_INLINE
+        size_type restrict_capacity (size_type non_zeros) const {
+            non_zeros = (std::max) (non_zeros, (std::min) (size1_, size2_));
+            // Guarding against overflow - Thanks to Alexei Novakov for the hint.
+            // non_zeros = (std::min) (non_zeros, size1_ * size2_);
+            if (size1_ > 0 && non_zeros / size1_ >= size2_)
+                non_zeros = size1_ * size2_;
+            return non_zeros;
+        }
+    public:
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            // FIXME preserve unimplemented
+            BOOST_UBLAS_CHECK (!preserve, internal_logic ());
+            size1_ = size1;
+            size2_ = size2;
+            capacity_ = restrict_capacity (capacity_);
+            filled1_ = 1;
+            filled2_ = 0;
+            index1_data_.resize (layout_type::size_M (size1_, size2_) + 1);
+            index2_data_.resize (capacity_);
+            value_data_.resize (capacity_);
+            index1_data_ [filled1_ - 1] = k_based (filled2_);
+            storage_invariants ();
+        }
+
+        // Reserving
+        BOOST_UBLAS_INLINE
+        void reserve (size_type non_zeros, bool preserve = true) {
+            capacity_ = restrict_capacity (non_zeros);
+            if (preserve) {
+                index2_data_.resize (capacity_, size_type ());
+                value_data_.resize (capacity_, value_type ());
+                filled2_ = (std::min) (capacity_, filled2_);
+            }
+            else {
+                index2_data_.resize (capacity_);
+                value_data_.resize (capacity_);
+                filled1_ = 1;
+                filled2_ = 0;
+                index1_data_ [filled1_ - 1] = k_based (filled2_);
+            }
+            storage_invariants ();
+       }
+
+        // Element support
+        BOOST_UBLAS_INLINE
+        pointer find_element (size_type i, size_type j) {
+            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i, j));
+        }
+        BOOST_UBLAS_INLINE
+        const_pointer find_element (size_type i, size_type j) const {
+            size_type element1 (layout_type::index_M (i, j));
+            size_type element2 (layout_type::index_m (i, j));
+            if (filled1_ <= element1 + 1)
+                return 0;
+            vector_const_subiterator_type itv (index1_data_.begin () + element1);
+            const_subiterator_type it_begin (index2_data_.begin () + zero_based (*itv));
+            const_subiterator_type it_end (index2_data_.begin () + zero_based (*(itv + 1)));
+            const_subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (element2), std::less<size_type> ()));
+            if (it == it_end || *it != k_based (element2))
+                return 0;
+            return &value_data_ [it - index2_data_.begin ()];
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            const_pointer p = find_element (i, j);
+            if (p)
+                return *p;
+            else
+                return zero_;
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE
+            size_type element1 (layout_type::index_M (i, j));
+            size_type element2 (layout_type::index_m (i, j));
+            if (filled1_ <= element1 + 1)
+                return insert_element (i, j, value_type/*zero*/());
+            pointer p = find_element (i, j);
+            if (p)
+                return *p;
+            else
+                return insert_element (i, j, value_type/*zero*/());
+#else
+            return reference (*this, i, j);
+#endif
+        }
+
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, size_type j, const_reference t) {
+            BOOST_UBLAS_CHECK (!find_element (i, j), bad_index ());        // duplicate element
+            if (filled2_ >= capacity_)
+                reserve (2 * filled2_, true);
+            BOOST_UBLAS_CHECK (filled2_ < capacity_, internal_logic ());
+            size_type element1 = layout_type::index_M (i, j);
+            size_type element2 = layout_type::index_m (i, j);
+            while (filled1_ <= element1 + 1) {
+                index1_data_ [filled1_] = k_based (filled2_);
+                ++ filled1_;
+            }
+            vector_subiterator_type itv (index1_data_.begin () + element1);
+            subiterator_type it_begin (index2_data_.begin () + zero_based (*itv));
+            subiterator_type it_end (index2_data_.begin () + zero_based (*(itv + 1)));
+            subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (element2), std::less<size_type> ()));
+            typename std::iterator_traits<subiterator_type>::difference_type n = it - index2_data_.begin ();
+            BOOST_UBLAS_CHECK (it == it_end || *it != k_based (element2), internal_logic ());   // duplicate bound by lower_bound
+            ++ filled2_;
+            it = index2_data_.begin () + n;
+            std::copy_backward (it, index2_data_.begin () + filled2_ - 1, index2_data_.begin () + filled2_);
+            *it = k_based (element2);
+            typename value_array_type::iterator itt (value_data_.begin () + n);
+            std::copy_backward (itt, value_data_.begin () + filled2_ - 1, value_data_.begin () + filled2_);
+            *itt = t;
+            while (element1 + 1 < filled1_) {
+                ++ index1_data_ [element1 + 1];
+                ++ element1;
+            }
+            storage_invariants ();
+            return *itt;
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i, size_type j) {
+            size_type element1 = layout_type::index_M (i, j);
+            size_type element2 = layout_type::index_m (i, j);
+            if (element1 + 1 >= filled1_)
+                return;
+            vector_subiterator_type itv (index1_data_.begin () + element1);
+            subiterator_type it_begin (index2_data_.begin () + zero_based (*itv));
+            subiterator_type it_end (index2_data_.begin () + zero_based (*(itv + 1)));
+            subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (element2), std::less<size_type> ()));
+            if (it != it_end && *it == k_based (element2)) {
+                typename std::iterator_traits<subiterator_type>::difference_type n = it - index2_data_.begin ();
+                std::copy (it + 1, index2_data_.begin () + filled2_, it);
+                typename value_array_type::iterator itt (value_data_.begin () + n);
+                std::copy (itt + 1, value_data_.begin () + filled2_, itt);
+                -- filled2_;
+                while (index1_data_ [filled1_ - 2] > k_based (filled2_)) {
+                    index1_data_ [filled1_ - 1] = 0;
+                    -- filled1_;
+                }
+                while (element1 + 1 < filled1_) {
+                    -- index1_data_ [element1 + 1];
+                    ++ element1;
+                }
+            }
+            storage_invariants ();
+        }
+        
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            filled1_ = 1;
+            filled2_ = 0;
+            index1_data_ [filled1_ - 1] = k_based (filled2_);
+            storage_invariants ();
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        compressed_matrix &operator = (const compressed_matrix &m) {
+            if (this != &m) {
+                size1_ = m.size1_;
+                size2_ = m.size2_;
+                capacity_ = m.capacity_;
+                filled1_ = m.filled1_;
+                filled2_ = m.filled2_;
+                index1_data_ = m.index1_data_;
+                index2_data_ = m.index2_data_;
+                value_data_ = m.value_data_;
+            }
+            storage_invariants ();
+            return *this;
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        compressed_matrix &operator = (const matrix_container<C> &m) {
+            resize (m ().size1 (), m ().size2 (), false);
+            assign (m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        compressed_matrix &assign_temporary (compressed_matrix &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_matrix &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_matrix &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_matrix& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        compressed_matrix &operator += (const matrix_container<C> &m) {
+            plus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_matrix &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_matrix& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        compressed_matrix &operator -= (const matrix_container<C> &m) {
+            minus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_matrix &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        compressed_matrix& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        compressed_matrix& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (compressed_matrix &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                std::swap (capacity_, m.capacity_);
+                std::swap (filled1_, m.filled1_);
+                std::swap (filled2_, m.filled2_);
+                index1_data_.swap (m.index1_data_);
+                index2_data_.swap (m.index2_data_);
+                value_data_.swap (m.value_data_);
+            }
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (compressed_matrix &m1, compressed_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Back element insertion and erasure
+        BOOST_UBLAS_INLINE
+        void push_back (size_type i, size_type j, const_reference t) {
+            if (filled2_ >= capacity_)
+                reserve (2 * filled2_, true);
+            BOOST_UBLAS_CHECK (filled2_ < capacity_, internal_logic ());
+            size_type element1 = layout_type::index_M (i, j);
+            size_type element2 = layout_type::index_m (i, j);
+            while (filled1_ < element1 + 2) {
+                index1_data_ [filled1_] = k_based (filled2_);
+                ++ filled1_;
+            }
+            // must maintain sort order
+            BOOST_UBLAS_CHECK ((filled1_ == element1 + 2 &&
+                                (filled2_ == zero_based (index1_data_ [filled1_ - 2]) ||
+                                index2_data_ [filled2_ - 1] < k_based (element2))), external_logic ());
+            ++ filled2_;
+            index1_data_ [filled1_ - 1] = k_based (filled2_);
+            index2_data_ [filled2_ - 1] = k_based (element2);
+            value_data_ [filled2_ - 1] = t;
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        void pop_back () {
+            BOOST_UBLAS_CHECK (filled1_ > 0 && filled2_ > 0, external_logic ());
+            -- filled2_;
+            while (index1_data_ [filled1_ - 2] > k_based (filled2_)) {
+                index1_data_ [filled1_ - 1] = 0;
+                -- filled1_;
+            }
+            -- index1_data_ [filled1_ - 1];
+            storage_invariants ();
+        }
+
+        // Iterator types
+    private:
+        // Use index array iterator
+        typedef typename IA::const_iterator vector_const_subiterator_type;
+        typedef typename IA::iterator vector_subiterator_type;
+        typedef typename IA::const_iterator const_subiterator_type;
+        typedef typename IA::iterator subiterator_type;
+
+        BOOST_UBLAS_INLINE
+        true_reference at_element (size_type i, size_type j) {
+            pointer p = find_element (i, j);
+            BOOST_UBLAS_CHECK (p, bad_index ());
+            return *p;
+        }
+
+    public:
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {
+            for (;;) {
+                array_size_type address1 (layout_type::index_M (i, j));
+                array_size_type address2 (layout_type::index_m (i, j));
+                vector_const_subiterator_type itv (index1_data_.begin () + (std::min) (filled1_ - 1, address1));
+                if (filled1_ <= address1 + 1)
+                    return const_iterator1 (*this, rank, i, j, itv, index2_data_.begin () + filled2_);
+
+                const_subiterator_type it_begin (index2_data_.begin () + zero_based (*itv));
+                const_subiterator_type it_end (index2_data_.begin () + zero_based (*(itv + 1)));
+
+                const_subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (address2), std::less<size_type> ()));
+                if (rank == 0)
+                    return const_iterator1 (*this, rank, i, j, itv, it);
+                if (it != it_end && zero_based (*it) == address2)
+                    return const_iterator1 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_i ()) {
+                        if (it == it_end)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        i = zero_based (*it);
+                    } else {
+                        if (i >= size1_)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        ++ i;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_i ()) {
+                        if (it == index2_data_.begin () + zero_based (*itv))
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        i = zero_based (*(it - 1));
+                    } else {
+                        if (i == 0)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        -- i;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {
+            for (;;) {
+                array_size_type address1 (layout_type::index_M (i, j));
+                array_size_type address2 (layout_type::index_m (i, j));
+                vector_subiterator_type itv (index1_data_.begin () + (std::min) (filled1_ - 1, address1));
+                if (filled1_ <= address1 + 1)
+                    return iterator1 (*this, rank, i, j, itv, index2_data_.begin () + filled2_);
+
+                subiterator_type it_begin (index2_data_.begin () + zero_based (*itv));
+                subiterator_type it_end (index2_data_.begin () + zero_based (*(itv + 1)));
+
+                subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (address2), std::less<size_type> ()));
+                if (rank == 0)
+                    return iterator1 (*this, rank, i, j, itv, it);
+                if (it != it_end && zero_based (*it) == address2)
+                    return iterator1 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_i ()) {
+                        if (it == it_end)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        i = zero_based (*it);
+                    } else {
+                        if (i >= size1_)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        ++ i;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_i ()) {
+                        if (it == index2_data_.begin () + zero_based (*itv))
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        i = zero_based (*(it - 1));
+                    } else {
+                        if (i == 0)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        -- i;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {
+            for (;;) {
+                array_size_type address1 (layout_type::index_M (i, j));
+                array_size_type address2 (layout_type::index_m (i, j));
+                vector_const_subiterator_type itv (index1_data_.begin () + (std::min) (filled1_ - 1, address1));
+                if (filled1_ <= address1 + 1)
+                    return const_iterator2 (*this, rank, i, j, itv, index2_data_.begin () + filled2_);
+
+                const_subiterator_type it_begin (index2_data_.begin () + zero_based (*itv));
+                const_subiterator_type it_end (index2_data_.begin () + zero_based (*(itv + 1)));
+
+                const_subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (address2), std::less<size_type> ()));
+                if (rank == 0)
+                    return const_iterator2 (*this, rank, i, j, itv, it);
+                if (it != it_end && zero_based (*it) == address2)
+                    return const_iterator2 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_j ()) {
+                        if (it == it_end)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        j = zero_based (*it);
+                    } else {
+                        if (j >= size2_)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        ++ j;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_j ()) {
+                        if (it == index2_data_.begin () + zero_based (*itv))
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        j = zero_based (*(it - 1));
+                    } else {
+                        if (j == 0)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        -- j;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {
+            for (;;) {
+                array_size_type address1 (layout_type::index_M (i, j));
+                array_size_type address2 (layout_type::index_m (i, j));
+                vector_subiterator_type itv (index1_data_.begin () + (std::min) (filled1_ - 1, address1));
+                if (filled1_ <= address1 + 1)
+                    return iterator2 (*this, rank, i, j, itv, index2_data_.begin () + filled2_);
+
+                subiterator_type it_begin (index2_data_.begin () + zero_based (*itv));
+                subiterator_type it_end (index2_data_.begin () + zero_based (*(itv + 1)));
+
+                subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (address2), std::less<size_type> ()));
+                if (rank == 0)
+                    return iterator2 (*this, rank, i, j, itv, it);
+                if (it != it_end && zero_based (*it) == address2)
+                    return iterator2 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_j ()) {
+                        if (it == it_end)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        j = zero_based (*it);
+                    } else {
+                        if (j >= size2_)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        ++ j;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_j ()) {
+                        if (it == index2_data_.begin () + zero_based (*itv))
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        j = zero_based (*(it - 1));
+                    } else {
+                        if (j == 0)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        -- j;
+                    }
+                }
+            }
+        }
+
+
+        class const_iterator1:
+            public container_const_reference<compressed_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename compressed_matrix::value_type value_type;
+            typedef typename compressed_matrix::difference_type difference_type;
+            typedef typename compressed_matrix::const_reference reference;
+            typedef const typename compressed_matrix::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, int rank, size_type i, size_type j, const vector_const_subiterator_type &itv, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    ++ it_;
+                else {
+                    i_ = index1 () + 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find1 (rank_, i_, j_, 1);
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    -- it_;
+                else {
+                    --i_;
+                    if (rank_ == 1)
+                        *this = (*this) ().find1 (rank_, i_, j_, -1);
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*this) ().value_data_ [it_ - (*this) ().index2_data_.begin ()];
+                } else {
+                    return (*this) () (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_)) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_));
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_)) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_));
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_const_subiterator_type itv_;
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+        class iterator1:
+            public container_reference<compressed_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename compressed_matrix::value_type value_type;
+            typedef typename compressed_matrix::difference_type difference_type;
+            typedef typename compressed_matrix::true_reference reference;
+            typedef typename compressed_matrix::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it):
+                container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    ++ it_;
+                else {
+                    i_ = index1 () + 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find1 (rank_, i_, j_, 1);
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    -- it_;
+                else {
+                    --i_;
+                    if (rank_ == 1)
+                        *this = (*this) ().find1 (rank_, i_, j_, -1);
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*this) ().value_data_ [it_ - (*this) ().index2_data_.begin ()];
+                } else {
+                    return (*this) ().at_element (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_)) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_));
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_)) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_));
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_subiterator_type itv_;
+            subiterator_type it_;
+
+            friend class const_iterator1;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1_, 0);
+        }
+
+        class const_iterator2:
+            public container_const_reference<compressed_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename compressed_matrix::value_type value_type;
+            typedef typename compressed_matrix::difference_type difference_type;
+            typedef typename compressed_matrix::const_reference reference;
+            typedef const typename compressed_matrix::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, int rank, size_type i, size_type j, const vector_const_subiterator_type itv, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    ++ it_;
+                else {
+                    j_ = index2 () + 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find2 (rank_, i_, j_, 1);
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    -- it_;
+                else {
+                    --j_;
+                    if (rank_ == 1)
+                        *this = (*this) ().find2 (rank_, i_, j_, -1);
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*this) ().value_data_ [it_ - (*this) ().index2_data_.begin ()];
+                } else {
+                    return (*this) () (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_)) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_));
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_)) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_));
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_const_subiterator_type itv_;
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        class iterator2:
+            public container_reference<compressed_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename compressed_matrix::value_type value_type;
+            typedef typename compressed_matrix::difference_type difference_type;
+            typedef typename compressed_matrix::true_reference reference;
+            typedef typename compressed_matrix::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it):
+                container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    ++ it_;
+                else {
+                    j_ = index2 () + 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find2 (rank_, i_, j_, 1);
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    -- it_;
+                else {
+                    --j_;
+                    if (rank_ == 1)
+                        *this = (*this) ().find2 (rank_, i_, j_, -1);
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*this) ().value_data_ [it_ - (*this) ().index2_data_.begin ()];
+                } else {
+                    return (*this) ().at_element (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_)) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_));
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_)) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m (itv_ - (*this) ().index1_data_.begin (), (*this) ().zero_based (*it_));
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_subiterator_type itv_;
+            subiterator_type it_;
+
+            friend class const_iterator2;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+            ar & serialization::make_nvp("size1",s1);
+            ar & serialization::make_nvp("size2",s2);
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+            }
+            ar & serialization::make_nvp("capacity", capacity_);
+            ar & serialization::make_nvp("filled1", filled1_);
+            ar & serialization::make_nvp("filled2", filled2_);
+            ar & serialization::make_nvp("index1_data", index1_data_);
+            ar & serialization::make_nvp("index2_data", index2_data_);
+            ar & serialization::make_nvp("value_data", value_data_);
+            storage_invariants();
+        }
+
+    private:
+        void storage_invariants () const {
+            BOOST_UBLAS_CHECK (layout_type::size_M (size1_, size2_) + 1 == index1_data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (capacity_ == index2_data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (capacity_ == value_data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (filled1_ > 0 && filled1_ <= layout_type::size_M (size1_, size2_) + 1, internal_logic ());
+            BOOST_UBLAS_CHECK (filled2_ <= capacity_, internal_logic ());
+            BOOST_UBLAS_CHECK (index1_data_ [filled1_ - 1] == k_based (filled2_), internal_logic ());
+        }
+        
+        size_type size1_;
+        size_type size2_;
+        array_size_type capacity_;
+        array_size_type filled1_;
+        array_size_type filled2_;
+        index_array_type index1_data_;
+        index_array_type index2_data_;
+        value_array_type value_data_;
+        static const value_type zero_;
+
+        BOOST_UBLAS_INLINE
+        static size_type zero_based (size_type k_based_index) {
+            return k_based_index - IB;
+        }
+        BOOST_UBLAS_INLINE
+        static size_type k_based (size_type zero_based_index) {
+            return zero_based_index + IB;
+        }
+
+        friend class iterator1;
+        friend class iterator2;
+        friend class const_iterator1;
+        friend class const_iterator2;
+    };
+
+    template<class T, class L, std::size_t IB, class IA, class TA>
+    const typename compressed_matrix<T, L, IB, IA, TA>::value_type compressed_matrix<T, L, IB, IA, TA>::zero_ = value_type/*zero*/();
+
+
+    // Coordinate array based sparse matrix class
+    // Thanks to Kresimir Fresl for extending this to cover different index bases.
+    template<class T, class L, std::size_t IB, class IA, class TA>
+    class coordinate_matrix:
+        public matrix_container<coordinate_matrix<T, L, IB, IA, TA> > {
+
+        typedef T &true_reference;
+        typedef T *pointer;
+        typedef const T *const_pointer;
+        typedef L layout_type;
+        typedef coordinate_matrix<T, L, IB, IA, TA> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        // ISSUE require type consistency check, is_convertable (IA::size_type, TA::size_type)
+        typedef typename IA::value_type size_type;
+        // ISSUE difference_type cannot be deduced for sparse indices, we only know the value_type
+        typedef std::ptrdiff_t difference_type;
+        // size_type for the data arrays.
+        typedef typename IA::size_type array_size_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE
+        typedef T &reference;
+#else
+        typedef sparse_matrix_element<self_type> reference;
+#endif
+        typedef IA index_array_type;
+        typedef TA value_array_type;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef coordinate_vector<T, IB, IA, TA> vector_temporary_type;
+        typedef self_type matrix_temporary_type;
+        typedef sparse_tag storage_category;
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        coordinate_matrix ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0), capacity_ (restrict_capacity (0)),
+            filled_ (0), sorted_filled_ (filled_), sorted_ (true),
+            index1_data_ (capacity_), index2_data_ (capacity_), value_data_ (capacity_) {
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        coordinate_matrix (size_type size1, size_type size2, array_size_type non_zeros = 0):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), capacity_ (restrict_capacity (non_zeros)),
+            filled_ (0), sorted_filled_ (filled_), sorted_ (true),
+            index1_data_ (capacity_), index2_data_ (capacity_), value_data_ (capacity_) {
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        coordinate_matrix (const coordinate_matrix &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_), capacity_ (m.capacity_),
+            filled_ (m.filled_), sorted_filled_ (m.sorted_filled_), sorted_ (m.sorted_),
+            index1_data_ (m.index1_data_), index2_data_ (m.index2_data_), value_data_ (m.value_data_) {
+            storage_invariants ();
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_matrix (const matrix_expression<AE> &ae, array_size_type non_zeros = 0):
+            matrix_container<self_type> (),
+            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), capacity_ (restrict_capacity (non_zeros)),
+            filled_ (0), sorted_filled_ (filled_), sorted_ (true),
+            index1_data_ (capacity_), index2_data_ (capacity_), value_data_ (capacity_) {
+            storage_invariants ();
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz_capacity () const {
+            return capacity_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz () const {
+            return filled_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        static size_type index_base () {
+            return IB;
+        }
+        BOOST_UBLAS_INLINE
+        array_size_type filled () const {
+            return filled_;
+        }
+        BOOST_UBLAS_INLINE
+        const index_array_type &index1_data () const {
+            return index1_data_;
+        }
+        BOOST_UBLAS_INLINE
+        const index_array_type &index2_data () const {
+            return index2_data_;
+        }
+        BOOST_UBLAS_INLINE
+        const value_array_type &value_data () const {
+            return value_data_;
+        }
+        BOOST_UBLAS_INLINE
+        void set_filled (const array_size_type &filled) {
+            // Make sure that storage_invariants() succeeds
+            if (sorted_ && filled < filled_)
+                sorted_filled_ = filled;
+            else
+                sorted_ = (sorted_filled_ == filled);
+            filled_ = filled;
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        index_array_type &index1_data () {
+            return index1_data_;
+        }
+        BOOST_UBLAS_INLINE
+        index_array_type &index2_data () {
+            return index2_data_;
+        }
+        BOOST_UBLAS_INLINE
+        value_array_type &value_data () {
+            return value_data_;
+        }
+
+        // Resizing
+    private:
+        BOOST_UBLAS_INLINE
+        array_size_type restrict_capacity (array_size_type non_zeros) const {
+            // minimum non_zeros
+            non_zeros = (std::max) (non_zeros, array_size_type((std::min) (size1_, size2_)));
+            // ISSUE no maximum as coordinate may contain inserted duplicates
+            return non_zeros;
+        }
+    public:
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            // FIXME preserve unimplemented
+            BOOST_UBLAS_CHECK (!preserve, internal_logic ());
+            size1_ = size1;
+            size2_ = size2;
+            capacity_ = restrict_capacity (capacity_);
+            index1_data_.resize (capacity_);
+            index2_data_.resize (capacity_);
+            value_data_.resize (capacity_);
+            filled_ = 0;
+            sorted_filled_ = filled_;
+            sorted_ = true;
+            storage_invariants ();
+        }
+
+        // Reserving
+        BOOST_UBLAS_INLINE
+        void reserve (array_size_type non_zeros, bool preserve = true) {
+            sort ();    // remove duplicate elements
+            capacity_ = restrict_capacity (non_zeros);
+            if (preserve) {
+                index1_data_.resize (capacity_, size_type ());
+                index2_data_.resize (capacity_, size_type ());
+                value_data_.resize (capacity_, value_type ());
+                filled_ = (std::min) (capacity_, filled_);
+            }
+            else {
+                index1_data_.resize (capacity_);
+                index2_data_.resize (capacity_);
+                value_data_.resize (capacity_);
+                filled_ = 0;
+            }
+            sorted_filled_ = filled_;
+            storage_invariants ();
+        }
+
+        // Element support
+        BOOST_UBLAS_INLINE
+        pointer find_element (size_type i, size_type j) {
+            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i, j));
+        }
+        BOOST_UBLAS_INLINE
+        const_pointer find_element (size_type i, size_type j) const {
+            sort ();
+            size_type element1 (layout_type::index_M (i, j));
+            size_type element2 (layout_type::index_m (i, j));
+            vector_const_subiterator_type itv_begin (detail::lower_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (element1), std::less<size_type> ()));
+            vector_const_subiterator_type itv_end (detail::upper_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (element1), std::less<size_type> ()));
+            if (itv_begin == itv_end)
+                return 0;
+            const_subiterator_type it_begin (index2_data_.begin () + (itv_begin - index1_data_.begin ()));
+            const_subiterator_type it_end (index2_data_.begin () + (itv_end - index1_data_.begin ()));
+            const_subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (element2), std::less<size_type> ()));
+            if (it == it_end || *it != k_based (element2))
+                return 0;
+            return &value_data_ [it - index2_data_.begin ()];
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            const_pointer p = find_element (i, j);
+            if (p)
+                return *p;
+            else 
+                return zero_;
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE
+            pointer p = find_element (i, j);
+            if (p)
+                return *p;
+            else
+                return insert_element (i, j, value_type/*zero*/());
+#else
+            return reference (*this, i, j);
+#endif
+        }
+
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        void append_element (size_type i, size_type j, const_reference t) {
+            if (filled_ >= capacity_)
+                reserve (2 * filled_, true);
+            BOOST_UBLAS_CHECK (filled_ < capacity_, internal_logic ());
+            size_type element1 = layout_type::index_M (i, j);
+            size_type element2 = layout_type::index_m (i, j);
+            index1_data_ [filled_] = k_based (element1);
+            index2_data_ [filled_] = k_based (element2);
+            value_data_ [filled_] = t;
+            ++ filled_;
+            sorted_ = false;
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, size_type j, const_reference t) {
+            BOOST_UBLAS_CHECK (!find_element (i, j), bad_index ());        // duplicate element
+            append_element (i, j, t);
+            return value_data_ [filled_ - 1];
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i, size_type j) {
+            size_type element1 = layout_type::index_M (i, j);
+            size_type element2 = layout_type::index_m (i, j);
+            sort ();
+            vector_subiterator_type itv_begin (detail::lower_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (element1), std::less<size_type> ()));
+            vector_subiterator_type itv_end (detail::upper_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (element1), std::less<size_type> ()));
+            subiterator_type it_begin (index2_data_.begin () + (itv_begin - index1_data_.begin ()));
+            subiterator_type it_end (index2_data_.begin () + (itv_end - index1_data_.begin ()));
+            subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (element2), std::less<size_type> ()));
+            if (it != it_end && *it == k_based (element2)) {
+                typename std::iterator_traits<subiterator_type>::difference_type n = it - index2_data_.begin ();
+                vector_subiterator_type itv (index1_data_.begin () + n);
+                std::copy (itv + 1, index1_data_.begin () + filled_, itv);
+                std::copy (it + 1, index2_data_.begin () + filled_, it);
+                typename value_array_type::iterator itt (value_data_.begin () + n);
+                std::copy (itt + 1, value_data_.begin () + filled_, itt);
+                -- filled_;
+                sorted_filled_ = filled_;
+            }
+            storage_invariants ();
+        }
+        
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            filled_ = 0;
+            sorted_filled_ = filled_;
+            sorted_ = true;
+            storage_invariants ();
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        coordinate_matrix &operator = (const coordinate_matrix &m) {
+            if (this != &m) {
+                size1_ = m.size1_;
+                size2_ = m.size2_;
+                capacity_ = m.capacity_;
+                filled_ = m.filled_;
+                sorted_filled_ = m.sorted_filled_;
+                sorted_ = m.sorted_;
+                index1_data_ = m.index1_data_;
+                index2_data_ = m.index2_data_;
+                value_data_ = m.value_data_;
+                BOOST_UBLAS_CHECK (capacity_ == index1_data_.size (), internal_logic ());
+                BOOST_UBLAS_CHECK (capacity_ == index2_data_.size (), internal_logic ());
+                BOOST_UBLAS_CHECK (capacity_ == value_data_.size (), internal_logic ());
+            }
+            storage_invariants ();
+            return *this;
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        coordinate_matrix &operator = (const matrix_container<C> &m) {
+            resize (m ().size1 (), m ().size2 (), false);
+            assign (m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        coordinate_matrix &assign_temporary (coordinate_matrix &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_matrix &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_matrix &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_matrix& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        coordinate_matrix &operator += (const matrix_container<C> &m) {
+            plus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_matrix &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_matrix& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        coordinate_matrix &operator -= (const matrix_container<C> &m) {
+            minus_assign (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_matrix &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        coordinate_matrix& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        coordinate_matrix& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (coordinate_matrix &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                std::swap (capacity_, m.capacity_);
+                std::swap (filled_, m.filled_);
+                std::swap (sorted_filled_, m.sorted_filled_);
+                std::swap (sorted_, m.sorted_);
+                index1_data_.swap (m.index1_data_);
+                index2_data_.swap (m.index2_data_);
+                value_data_.swap (m.value_data_);
+            }
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (coordinate_matrix &m1, coordinate_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // replacement if STL lower bound algorithm for use of inplace_merge
+        array_size_type lower_bound (array_size_type beg, array_size_type end, array_size_type target) const {
+            while (end > beg) {
+                array_size_type mid = (beg + end) / 2;
+                if (((index1_data_[mid] < index1_data_[target]) ||
+                     ((index1_data_[mid] == index1_data_[target]) &&
+                      (index2_data_[mid] < index2_data_[target])))) {
+                    beg = mid + 1;
+                } else {
+                    end = mid;
+                }
+            }
+            return beg;
+        }
+
+        // specialized replacement of STL inplace_merge to avoid compilation
+        // problems with respect to the array_triple iterator
+        void inplace_merge (array_size_type beg, array_size_type mid, array_size_type end) const {
+            array_size_type len_lef = mid - beg;
+            array_size_type len_rig = end - mid;
+
+            if (len_lef == 1 && len_rig == 1) {
+                if ((index1_data_[mid] < index1_data_[beg]) ||
+                    ((index1_data_[mid] == index1_data_[beg]) && (index2_data_[mid] < index2_data_[beg])))
+                    {
+                        std::swap(index1_data_[beg], index1_data_[mid]);
+                        std::swap(index2_data_[beg], index2_data_[mid]);
+                        std::swap(value_data_[beg], value_data_[mid]);
+                    }
+            } else if (len_lef > 0 && len_rig > 0) {
+                array_size_type lef_mid, rig_mid;
+                if (len_lef >= len_rig) {
+                    lef_mid = (beg + mid) / 2;
+                    rig_mid = lower_bound(mid, end, lef_mid);
+                } else {
+                    rig_mid = (mid + end) / 2;
+                    lef_mid = lower_bound(beg, mid, rig_mid);
+                }
+                std::rotate(&index1_data_[0] + lef_mid, &index1_data_[0] + mid, &index1_data_[0] + rig_mid);
+                std::rotate(&index2_data_[0] + lef_mid, &index2_data_[0] + mid, &index2_data_[0] + rig_mid);
+                std::rotate(&value_data_[0] + lef_mid, &value_data_[0] + mid, &value_data_[0] + rig_mid);
+
+                array_size_type new_mid = lef_mid + rig_mid - mid;
+                inplace_merge(beg, lef_mid, new_mid);
+                inplace_merge(new_mid, rig_mid, end);
+            }
+        }
+
+        // Sorting and summation of duplicates
+        BOOST_UBLAS_INLINE
+        void sort () const {
+            if (! sorted_ && filled_ > 0) {
+                typedef index_triple_array<index_array_type, index_array_type, value_array_type> array_triple;
+                array_triple ita (filled_, index1_data_, index2_data_, value_data_);
+#ifndef BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT
+                const typename array_triple::iterator iunsorted = ita.begin () + sorted_filled_;
+                // sort new elements and merge
+                std::sort (iunsorted, ita.end ());
+                inplace_merge(0, sorted_filled_, filled_);
+#else
+                const typename array_triple::iterator iunsorted = ita.begin ();
+                std::sort (iunsorted, ita.end ());
+#endif                
+                // sum duplicates with += and remove
+                array_size_type filled = 0;
+                for (array_size_type i = 1; i < filled_; ++ i) {
+                    if (index1_data_ [filled] != index1_data_ [i] ||
+                        index2_data_ [filled] != index2_data_ [i]) {
+                        ++ filled;
+                        if (filled != i) {
+                            index1_data_ [filled] = index1_data_ [i];
+                            index2_data_ [filled] = index2_data_ [i];
+                            value_data_ [filled] = value_data_ [i];
+                        }
+                    } else {
+                        value_data_ [filled] += value_data_ [i];
+                    }
+                }
+                filled_ = filled + 1;
+                sorted_filled_ = filled_;
+                sorted_ = true;
+                storage_invariants ();
+            }
+        }
+
+        // Back element insertion and erasure
+        BOOST_UBLAS_INLINE
+        void push_back (size_type i, size_type j, const_reference t) {
+            size_type element1 = layout_type::index_M (i, j);
+            size_type element2 = layout_type::index_m (i, j);
+            // must maintain sort order
+            BOOST_UBLAS_CHECK (sorted_ && 
+                    (filled_ == 0 ||
+                    index1_data_ [filled_ - 1] < k_based (element1) ||
+                    (index1_data_ [filled_ - 1] == k_based (element1) && index2_data_ [filled_ - 1] < k_based (element2)))
+                    , external_logic ());
+            if (filled_ >= capacity_)
+                reserve (2 * filled_, true);
+            BOOST_UBLAS_CHECK (filled_ < capacity_, internal_logic ());
+            index1_data_ [filled_] = k_based (element1);
+            index2_data_ [filled_] = k_based (element2);
+            value_data_ [filled_] = t;
+            ++ filled_;
+            sorted_filled_ = filled_;
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        void pop_back () {
+            // ISSUE invariants could be simpilfied if sorted required as precondition
+            BOOST_UBLAS_CHECK (filled_ > 0, external_logic ());
+            -- filled_;
+            sorted_filled_ = (std::min) (sorted_filled_, filled_);
+            sorted_ = sorted_filled_ = filled_;
+            storage_invariants ();
+        }
+
+        // Iterator types
+    private:
+        // Use index array iterator
+        typedef typename IA::const_iterator vector_const_subiterator_type;
+        typedef typename IA::iterator vector_subiterator_type;
+        typedef typename IA::const_iterator const_subiterator_type;
+        typedef typename IA::iterator subiterator_type;
+
+        BOOST_UBLAS_INLINE
+        true_reference at_element (size_type i, size_type j) {
+            pointer p = find_element (i, j);
+            BOOST_UBLAS_CHECK (p, bad_index ());
+            return *p;
+        }
+
+    public:
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {
+            sort ();
+            for (;;) {
+                size_type address1 (layout_type::index_M (i, j));
+                size_type address2 (layout_type::index_m (i, j));
+                vector_const_subiterator_type itv_begin (detail::lower_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (address1), std::less<size_type> ()));
+                vector_const_subiterator_type itv_end (detail::upper_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (address1), std::less<size_type> ()));
+
+                const_subiterator_type it_begin (index2_data_.begin () + (itv_begin - index1_data_.begin ()));
+                const_subiterator_type it_end (index2_data_.begin () + (itv_end - index1_data_.begin ()));
+
+                const_subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (address2), std::less<size_type> ()));
+                vector_const_subiterator_type itv (index1_data_.begin () + (it - index2_data_.begin ()));
+                if (rank == 0)
+                    return const_iterator1 (*this, rank, i, j, itv, it);
+                if (it != it_end && zero_based (*it) == address2)
+                    return const_iterator1 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_i ()) {
+                        if (it == it_end)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        i = zero_based (*it);
+                    } else {
+                        if (i >= size1_)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        ++ i;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_i ()) {
+                        if (it == index2_data_.begin () + array_size_type (zero_based (*itv)))
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        i = zero_based (*(it - 1));
+                    } else {
+                        if (i == 0)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        -- i;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {
+            sort ();
+            for (;;) {
+                size_type address1 (layout_type::index_M (i, j));
+                size_type address2 (layout_type::index_m (i, j));
+                vector_subiterator_type itv_begin (detail::lower_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (address1), std::less<size_type> ()));
+                vector_subiterator_type itv_end (detail::upper_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (address1), std::less<size_type> ()));
+
+                subiterator_type it_begin (index2_data_.begin () + (itv_begin - index1_data_.begin ()));
+                subiterator_type it_end (index2_data_.begin () + (itv_end - index1_data_.begin ()));
+
+                subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (address2), std::less<size_type> ()));
+                vector_subiterator_type itv (index1_data_.begin () + (it - index2_data_.begin ()));
+                if (rank == 0)
+                    return iterator1 (*this, rank, i, j, itv, it);
+                if (it != it_end && zero_based (*it) == address2)
+                    return iterator1 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_i ()) {
+                        if (it == it_end)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        i = zero_based (*it);
+                    } else {
+                        if (i >= size1_)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        ++ i;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_i ()) {
+                        if (it == index2_data_.begin () + array_size_type (zero_based (*itv)))
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        i = zero_based (*(it - 1));
+                    } else {
+                        if (i == 0)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        -- i;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {
+            sort ();
+            for (;;) {
+                size_type address1 (layout_type::index_M (i, j));
+                size_type address2 (layout_type::index_m (i, j));
+                vector_const_subiterator_type itv_begin (detail::lower_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (address1), std::less<size_type> ()));
+                vector_const_subiterator_type itv_end (detail::upper_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (address1), std::less<size_type> ()));
+
+                const_subiterator_type it_begin (index2_data_.begin () + (itv_begin - index1_data_.begin ()));
+                const_subiterator_type it_end (index2_data_.begin () + (itv_end - index1_data_.begin ()));
+
+                const_subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (address2), std::less<size_type> ()));
+                vector_const_subiterator_type itv (index1_data_.begin () + (it - index2_data_.begin ()));
+                if (rank == 0)
+                    return const_iterator2 (*this, rank, i, j, itv, it);
+                if (it != it_end && zero_based (*it) == address2)
+                    return const_iterator2 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_j ()) {
+                        if (it == it_end)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        j = zero_based (*it);
+                    } else {
+                        if (j >= size2_)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        ++ j;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_j ()) {
+                        if (it == index2_data_.begin () + array_size_type (zero_based (*itv)))
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        j = zero_based (*(it - 1));
+                    } else {
+                        if (j == 0)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        -- j;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {
+            sort ();
+            for (;;) {
+                size_type address1 (layout_type::index_M (i, j));
+                size_type address2 (layout_type::index_m (i, j));
+                vector_subiterator_type itv_begin (detail::lower_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (address1), std::less<size_type> ()));
+                vector_subiterator_type itv_end (detail::upper_bound (index1_data_.begin (), index1_data_.begin () + filled_, k_based (address1), std::less<size_type> ()));
+
+                subiterator_type it_begin (index2_data_.begin () + (itv_begin - index1_data_.begin ()));
+                subiterator_type it_end (index2_data_.begin () + (itv_end - index1_data_.begin ()));
+
+                subiterator_type it (detail::lower_bound (it_begin, it_end, k_based (address2), std::less<size_type> ()));
+                vector_subiterator_type itv (index1_data_.begin () + (it - index2_data_.begin ()));
+                if (rank == 0)
+                    return iterator2 (*this, rank, i, j, itv, it);
+                if (it != it_end && zero_based (*it) == address2)
+                    return iterator2 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_j ()) {
+                        if (it == it_end)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        j = zero_based (*it);
+                    } else {
+                        if (j >= size2_)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        ++ j;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_j ()) {
+                        if (it == index2_data_.begin () + array_size_type (zero_based (*itv)))
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        j = zero_based (*(it - 1));
+                    } else {
+                        if (j == 0)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        -- j;
+                    }
+                }
+            }
+        }
+
+
+        class const_iterator1:
+            public container_const_reference<coordinate_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename coordinate_matrix::value_type value_type;
+            typedef typename coordinate_matrix::difference_type difference_type;
+            typedef typename coordinate_matrix::const_reference reference;
+            typedef const typename coordinate_matrix::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, int rank, size_type i, size_type j, const vector_const_subiterator_type &itv, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    ++ it_;
+                else {
+                    i_ = index1 () + 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find1 (rank_, i_, j_, 1);
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    -- it_;
+                else {
+                    i_ = index1 () - 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find1 (rank_, i_, j_, -1);
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*this) ().value_data_ [it_ - (*this) ().index2_data_.begin ()];
+                } else {
+                    return (*this) () (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_)) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_));
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_)) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_));
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_const_subiterator_type itv_;
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+        class iterator1:
+            public container_reference<coordinate_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename coordinate_matrix::value_type value_type;
+            typedef typename coordinate_matrix::difference_type difference_type;
+            typedef typename coordinate_matrix::true_reference reference;
+            typedef typename coordinate_matrix::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it):
+                container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    ++ it_;
+                else {
+                    i_ = index1 () + 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find1 (rank_, i_, j_, 1);
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    -- it_;
+                else {
+                    i_ = index1 () - 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find1 (rank_, i_, j_, -1);
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*this) ().value_data_ [it_ - (*this) ().index2_data_.begin ()];
+                } else {
+                    return (*this) ().at_element (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_)) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_));
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_)) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_));
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_subiterator_type itv_;
+            subiterator_type it_;
+
+            friend class const_iterator1;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1_, 0);
+        }
+
+        class const_iterator2:
+            public container_const_reference<coordinate_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename coordinate_matrix::value_type value_type;
+            typedef typename coordinate_matrix::difference_type difference_type;
+            typedef typename coordinate_matrix::const_reference reference;
+            typedef const typename coordinate_matrix::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, int rank, size_type i, size_type j, const vector_const_subiterator_type itv, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    ++ it_;
+                else {
+                    j_ = index2 () + 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find2 (rank_, i_, j_, 1);
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    -- it_;
+                else {
+                    j_ = index2 () - 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find2 (rank_, i_, j_, -1);
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*this) ().value_data_ [it_ - (*this) ().index2_data_.begin ()];
+                } else {
+                    return (*this) () (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_)) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_));
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_)) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_));
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_const_subiterator_type itv_;
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        class iterator2:
+            public container_reference<coordinate_matrix>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename coordinate_matrix::value_type value_type;
+            typedef typename coordinate_matrix::difference_type difference_type;
+            typedef typename coordinate_matrix::true_reference reference;
+            typedef typename coordinate_matrix::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, int rank, size_type i, size_type j, const vector_subiterator_type &itv, const subiterator_type &it):
+                container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    ++ it_;
+                else {
+                    j_ = index2 () + 1;
+                    if (rank_ == 1)
+                        *this = (*this) ().find2 (rank_, i_, j_, 1);
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    -- it_;
+                else {
+                    j_ = index2 ();
+                    if (rank_ == 1)
+                        *this = (*this) ().find2 (rank_, i_, j_, -1);
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return (*this) ().value_data_ [it_ - (*this) ().index2_data_.begin ()];
+                } else {
+                    return (*this) ().at_element (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_)) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_));
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_)) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m ((*this) ().zero_based (*itv_), (*this) ().zero_based (*it_));
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vector_subiterator_type itv_;
+            subiterator_type it_;
+
+            friend class const_iterator2;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+            ar & serialization::make_nvp("size1",s1);
+            ar & serialization::make_nvp("size2",s2);
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+            }
+            ar & serialization::make_nvp("capacity", capacity_);
+            ar & serialization::make_nvp("filled", filled_);
+            ar & serialization::make_nvp("sorted_filled", sorted_filled_);
+            ar & serialization::make_nvp("sorted", sorted_);
+            ar & serialization::make_nvp("index1_data", index1_data_);
+            ar & serialization::make_nvp("index2_data", index2_data_);
+            ar & serialization::make_nvp("value_data", value_data_);
+            storage_invariants();
+        }
+
+    private:
+        void storage_invariants () const
+        {
+            BOOST_UBLAS_CHECK (capacity_ == index1_data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (capacity_ == index2_data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (capacity_ == value_data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (filled_ <= capacity_, internal_logic ());
+            BOOST_UBLAS_CHECK (sorted_filled_ <= filled_, internal_logic ());
+            BOOST_UBLAS_CHECK (sorted_ == (sorted_filled_ == filled_), internal_logic ());
+        }
+
+        size_type size1_;
+        size_type size2_;
+        array_size_type capacity_;
+        mutable array_size_type filled_;
+        mutable array_size_type sorted_filled_;
+        mutable bool sorted_;
+        mutable index_array_type index1_data_;
+        mutable index_array_type index2_data_;
+        mutable value_array_type value_data_;
+        static const value_type zero_;
+
+        BOOST_UBLAS_INLINE
+        static size_type zero_based (size_type k_based_index) {
+            return k_based_index - IB;
+        }
+        BOOST_UBLAS_INLINE
+        static size_type k_based (size_type zero_based_index) {
+            return zero_based_index + IB;
+        }
+
+        friend class iterator1;
+        friend class iterator2;
+        friend class const_iterator1;
+        friend class const_iterator2;
+    };
+
+    template<class T, class L, std::size_t IB, class IA, class TA>
+    const typename coordinate_matrix<T, L, IB, IA, TA>::value_type coordinate_matrix<T, L, IB, IA, TA>::zero_ = value_type/*zero*/();
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/matrix_vector.hpp b/include/boost/numeric/ublas/matrix_vector.hpp
new file mode 100644
index 0000000..fec1f65
--- /dev/null
+++ b/include/boost/numeric/ublas/matrix_vector.hpp
@@ -0,0 +1,348 @@
+//  Copyright (c) 2012 Oswin Krause
+//  Copyright (c) 2013 Joaquim Duran
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_UBLAS_MATRIX_VECTOR_HPP
+#define BOOST_UBLAS_MATRIX_VECTOR_HPP
+
+#include <boost/numeric/ublas/matrix_proxy.hpp>//for matrix_row, matrix_column and matrix_expression
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace numeric { namespace ublas {
+
+namespace detail{
+
+/** \brief Iterator used in the represention of a matrix as a vector of rows or columns
+ *
+ * Iterator used in the represention of a matrix as a vector of rows/columns. It refers
+ * to the i-th element of the matrix, a column or a row depending of Reference type.
+ *
+ * The type of Reference should provide a constructor Reference(matrix, i)
+ *
+ * This iterator is invalidated when the underlying matrix is resized.
+ *
+ * \tparameter Matrix type of matrix that is represented as a vector of row/column
+ * \tparameter Reference Matrix row or matrix column type.
+ */
+template<class Matrix, class Reference>
+class matrix_vector_iterator: public boost::iterator_facade<
+    matrix_vector_iterator<Matrix,Reference>,
+    typename vector_temporary_traits<Reference>::type,
+    boost::random_access_traversal_tag,
+    Reference
+>{
+public:
+    matrix_vector_iterator(){}
+
+    ///\brief constructs a matrix_vector_iterator as pointing to the i-th proxy
+    matrix_vector_iterator(Matrix& matrix, std::size_t position)
+    : matrix_(&matrix),position_(position) {}
+
+    template<class M, class R>
+    matrix_vector_iterator(matrix_vector_iterator<M,R> const& other)
+    : matrix_(other.matrix_),position_(other.position_) {}
+
+private:
+    friend class boost::iterator_core_access;
+    template <class M,class R> friend class matrix_vector_iterator;
+
+    void increment() {
+        ++position_;
+    }
+    void decrement() {
+        --position_;
+    }
+
+    void advance(std::ptrdiff_t n){
+        position_ += n;
+    }
+
+    template<class M,class R>
+    std::ptrdiff_t distance_to(matrix_vector_iterator<M,R> const& other) const{
+        BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ());
+        return (std::ptrdiff_t)other.position_ - (std::ptrdiff_t)position_;
+    }
+
+    template<class M,class R>
+    bool equal(matrix_vector_iterator<M,R> const& other) const{
+        BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ());
+        return (position_ == other.position_);
+    }
+    Reference dereference() const {
+        return Reference(*matrix_,position_);
+    }
+
+    Matrix* matrix_;//no matrix_closure here to ensure easy usage
+    std::size_t position_;
+};
+
+}
+
+/** \brief Represents a \c Matrix as a vector of rows.
+ *
+ * Implements an interface to Matrix that the underlaying matrix is represented as a
+ * vector of rows.
+ *
+ * The vector could be resized which causes the resize of the number of rows of
+ * the underlaying matrix.
+ */
+template<class Matrix>
+class matrix_row_vector {
+public:
+    typedef ublas::matrix_row<Matrix> value_type;
+    typedef ublas::matrix_row<Matrix> reference;
+    typedef ublas::matrix_row<Matrix const> const_reference;
+
+    typedef ublas::detail::matrix_vector_iterator<Matrix, ublas::matrix_row<Matrix> > iterator;
+    typedef ublas::detail::matrix_vector_iterator<Matrix const, ublas::matrix_row<Matrix const> const> const_iterator;
+    typedef boost::reverse_iterator<iterator> reverse_iterator;
+    typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
+
+    typedef typename boost::iterator_difference<iterator>::type difference_type;
+    typedef typename Matrix::size_type size_type;
+
+    matrix_row_vector(Matrix& matrix) :
+        matrix_(matrix) {
+    }
+
+
+    iterator begin(){
+        return iterator(matrix_, 0);
+    }
+
+    const_iterator begin() const {
+        return const_iterator(matrix_, 0);
+    }
+
+    const_iterator cbegin() const {
+        return begin();
+    }
+
+    iterator end() {
+        return iterator(matrix_, matrix_.size1());
+    }
+
+    const_iterator end() const {
+        return const_iterator(matrix_, matrix_.size1());
+    }
+
+    const_iterator cend() const {
+        return end();
+    }
+
+    reverse_iterator rbegin() {
+        return reverse_iterator(end());
+    }
+
+    const_reverse_iterator rbegin() const {
+        return const_reverse_iterator(end());
+    }
+
+    const_reverse_iterator crbegin() const {
+        return rbegin();
+    }  
+
+    reverse_iterator rend() {
+        return reverse_iterator(begin());
+    }
+
+    const_reverse_iterator rend() const {
+        return const_reverse_iterator(begin());
+    }
+
+    const_reverse_iterator crend() const {
+        return end();
+    }
+
+    value_type operator()(difference_type index) const {
+        return value_type(matrix_, index);
+    }
+
+    reference operator[](difference_type index){
+        return reference(matrix_, index);
+    }
+
+    const_reference operator[](difference_type index) const {
+        return const_reference(matrix_, index);
+    }
+
+    size_type size() const {
+        return matrix_.size1();
+    }
+
+    void resize(size_type size, bool preserve = true) {
+        matrix_.resize(size, matrix_.size2(), preserve);
+    }
+
+private:
+    Matrix& matrix_;
+};
+
+
+/** \brief Convenience function to create \c matrix_row_vector.
+ *
+ * Function to create \c matrix_row_vector objects.
+ * \param matrix the \c matrix_expression that generates the matrix that \c matrix_row_vector is referring.
+ * \return Created \c matrix_row_vector object.
+ *
+ * \tparam Matrix the type of matrix that \c matrix_row_vector is referring.
+ */
+template<class Matrix>
+matrix_row_vector<Matrix> make_row_vector(matrix_expression<Matrix>& matrix){
+    return matrix_row_vector<Matrix>(matrix());
+}
+
+
+/** \brief Convenience function to create \c matrix_row_vector.
+ *
+ * Function to create \c matrix_row_vector objects.
+ * \param matrix the \c matrix_expression that generates the matrix that \c matrix_row_vector is referring.
+ * \return Created \c matrix_row_vector object.
+ *
+ * \tparam Matrix the type of matrix that \c matrix_row_vector is referring.
+ */
+template<class Matrix>
+matrix_row_vector<Matrix const> make_row_vector(matrix_expression<Matrix> const& matrix){
+    return matrix_row_vector<Matrix const>(matrix());
+}
+
+
+/** \brief Represents a \c Matrix as a vector of columns.
+ *
+ * Implements an interface to Matrix that the underlaying matrix is represented as a
+ * vector of columns.
+ *
+ * The vector could be resized which causes the resize of the number of columns of
+ * the underlaying matrix.
+ */
+template<class Matrix>
+class matrix_column_vector
+{
+public:
+    typedef ublas::matrix_column<Matrix> value_type;
+    typedef ublas::matrix_column<Matrix> reference;
+    typedef const ublas::matrix_column<Matrix const> const_reference;
+
+    typedef ublas::detail::matrix_vector_iterator<Matrix, ublas::matrix_column<Matrix> > iterator;
+    typedef ublas::detail::matrix_vector_iterator<Matrix const, ublas::matrix_column<Matrix const> const > const_iterator;
+    typedef boost::reverse_iterator<iterator> reverse_iterator;
+    typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
+
+    typedef typename boost::iterator_difference<iterator>::type difference_type;
+    typedef typename Matrix::size_type size_type;
+
+    matrix_column_vector(Matrix& matrix) :
+        matrix_(matrix){
+    }
+
+    iterator begin() {
+        return iterator(matrix_, 0);
+    }
+
+    const_iterator begin() const {
+        return const_iterator(matrix_, 0);
+    }
+
+    const_iterator cbegin() const {
+        return begin();
+    }
+
+    iterator end() {
+        return iterator(matrix_, matrix_.size2());
+    }
+
+    const_iterator end() const {
+        return const_iterator(matrix_, matrix_.size2());
+    }
+
+    const_iterator cend() const {
+        return end();
+    }
+
+    reverse_iterator rbegin() {
+        return reverse_iterator(end());
+    }
+
+    const_reverse_iterator rbegin() const {
+        return const_reverse_iterator(end());
+    }
+
+    const_reverse_iterator crbegin() const {
+        return rbegin();
+    } 
+
+    reverse_iterator rend() {
+        return reverse_iterator(begin());
+    }
+
+    const_reverse_iterator rend() const {
+        return const_reverse_iterator(begin());
+    }
+
+    const_reverse_iterator crend() const {
+        return rend();
+    }
+
+    value_type operator()(difference_type index) const {
+        return value_type(matrix_, index);
+    }
+
+    reference operator[](difference_type index) {
+        return reference(matrix_, index);
+    }
+
+    const_reference operator[](difference_type index) const {
+        return const_reference(matrix_, index);
+    }
+
+    size_type size() const {
+        return matrix_.size2();
+    }
+
+    void resize(size_type size, bool preserve = true) {
+        matrix_.resize(matrix_.size1(), size, preserve);
+    }
+
+private:
+    Matrix& matrix_;
+};
+
+
+/** \brief Convenience function to create \c matrix_column_vector.
+ *
+ * Function to create \c matrix_column_vector objects.
+ * \param matrix the \c matrix_expression that generates the matrix that \c matrix_column_vector is referring.
+ * \return Created \c matrix_column_vector object.
+ *
+ * \tparam Matrix the type of matrix that \c matrix_column_vector is referring.
+ */
+template<class Matrix>
+matrix_column_vector<Matrix> make_column_vector(matrix_expression<Matrix>& matrix){
+    return matrix_column_vector<Matrix>(matrix());
+}
+
+
+/** \brief Convenience function to create \c matrix_column_vector.
+ *
+ * Function to create \c matrix_column_vector objects.
+ * \param matrix the \c matrix_expression that generates the matrix that \c matrix_column_vector is referring.
+ * \return Created \c matrix_column_vector object.
+ *
+ * \tparam Matrix the type of matrix that \c matrix_column_vector is referring.
+ */
+template<class Matrix>
+matrix_column_vector<Matrix const> make_column_vector(matrix_expression<Matrix> const& matrix){
+    return matrix_column_vector<Matrix const>(matrix());
+}
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/operation.hpp b/include/boost/numeric/ublas/operation.hpp
new file mode 100644
index 0000000..64657cc
--- /dev/null
+++ b/include/boost/numeric/ublas/operation.hpp
@@ -0,0 +1,830 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_OPERATION_
+#define _BOOST_UBLAS_OPERATION_
+
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+
+/** \file operation.hpp
+ *  \brief This file contains some specialized products.
+ */
+
+// axpy-based products
+// Alexei Novakov had a lot of ideas to improve these. Thanks.
+// Hendrik Kueck proposed some new kernel. Thanks again.
+
+namespace boost { namespace numeric { namespace ublas {
+
+    template<class V, class T1, class L1, class IA1, class TA1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const compressed_matrix<T1, L1, 0, IA1, TA1> &e1,
+               const vector_expression<E2> &e2,
+               V &v, row_major_tag) {
+        typedef typename V::size_type size_type;
+        typedef typename V::value_type value_type;
+
+        for (size_type i = 0; i < e1.filled1 () -1; ++ i) {
+            size_type begin = e1.index1_data () [i];
+            size_type end = e1.index1_data () [i + 1];
+            value_type t (v (i));
+            for (size_type j = begin; j < end; ++ j)
+                t += e1.value_data () [j] * e2 () (e1.index2_data () [j]);
+            v (i) = t;
+        }
+        return v;
+    }
+
+    template<class V, class T1, class L1, class IA1, class TA1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const compressed_matrix<T1, L1, 0, IA1, TA1> &e1,
+               const vector_expression<E2> &e2,
+               V &v, column_major_tag) {
+        typedef typename V::size_type size_type;
+
+        for (size_type j = 0; j < e1.filled1 () -1; ++ j) {
+            size_type begin = e1.index1_data () [j];
+            size_type end = e1.index1_data () [j + 1];
+            for (size_type i = begin; i < end; ++ i)
+                v (e1.index2_data () [i]) += e1.value_data () [i] * e2 () (j);
+        }
+        return v;
+    }
+
+    // Dispatcher
+    template<class V, class T1, class L1, class IA1, class TA1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const compressed_matrix<T1, L1, 0, IA1, TA1> &e1,
+               const vector_expression<E2> &e2,
+               V &v, bool init = true) {
+        typedef typename V::value_type value_type;
+        typedef typename L1::orientation_category orientation_category;
+
+        if (init)
+            v.assign (zero_vector<value_type> (e1.size1 ()));
+#if BOOST_UBLAS_TYPE_CHECK
+        vector<value_type> cv (v);
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
+        indexing_vector_assign<scalar_plus_assign> (cv, prod (e1, e2));
+#endif
+        axpy_prod (e1, e2, v, orientation_category ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
+#endif
+        return v;
+    }
+    template<class V, class T1, class L1, class IA1, class TA1, class E2>
+    BOOST_UBLAS_INLINE
+    V
+    axpy_prod (const compressed_matrix<T1, L1, 0, IA1, TA1> &e1,
+               const vector_expression<E2> &e2) {
+        typedef V vector_type;
+
+        vector_type v (e1.size1 ());
+        return axpy_prod (e1, e2, v, true);
+    }
+
+    template<class V, class T1, class L1, class IA1, class TA1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const coordinate_matrix<T1, L1, 0, IA1, TA1> &e1,
+               const vector_expression<E2> &e2,
+               V &v, bool init = true) {
+        typedef typename V::size_type size_type;
+        typedef typename V::value_type value_type;
+        typedef L1 layout_type;
+
+        size_type size1 = e1.size1();
+        size_type size2 = e1.size2();
+
+        if (init) {
+            noalias(v) = zero_vector<value_type>(size1);
+        }
+
+        for (size_type i = 0; i < e1.nnz(); ++i) {
+            size_type row_index = layout_type::index_M( e1.index1_data () [i], e1.index2_data () [i] );
+            size_type col_index = layout_type::index_m( e1.index1_data () [i], e1.index2_data () [i] );
+            v( row_index ) += e1.value_data () [i] * e2 () (col_index);
+        }
+        return v;
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const vector_expression<E2> &e2,
+               V &v, packed_random_access_iterator_tag, row_major_tag) {
+        typedef const E1 expression1_type;
+        typedef typename V::size_type size_type;
+
+        typename expression1_type::const_iterator1 it1 (e1 ().begin1 ());
+        typename expression1_type::const_iterator1 it1_end (e1 ().end1 ());
+        while (it1 != it1_end) {
+            size_type index1 (it1.index1 ());
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename expression1_type::const_iterator2 it2 (it1.begin ());
+            typename expression1_type::const_iterator2 it2_end (it1.end ());
+#else
+            typename expression1_type::const_iterator2 it2 (boost::numeric::ublas::begin (it1, iterator1_tag ()));
+            typename expression1_type::const_iterator2 it2_end (boost::numeric::ublas::end (it1, iterator1_tag ()));
+#endif
+            while (it2 != it2_end) {
+                v (index1) += *it2 * e2 () (it2.index2 ());
+                ++ it2;
+            }
+            ++ it1;
+        }
+        return v;
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const vector_expression<E2> &e2,
+               V &v, packed_random_access_iterator_tag, column_major_tag) {
+        typedef const E1 expression1_type;
+        typedef typename V::size_type size_type;
+
+        typename expression1_type::const_iterator2 it2 (e1 ().begin2 ());
+        typename expression1_type::const_iterator2 it2_end (e1 ().end2 ());
+        while (it2 != it2_end) {
+            size_type index2 (it2.index2 ());
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename expression1_type::const_iterator1 it1 (it2.begin ());
+            typename expression1_type::const_iterator1 it1_end (it2.end ());
+#else
+            typename expression1_type::const_iterator1 it1 (boost::numeric::ublas::begin (it2, iterator2_tag ()));
+            typename expression1_type::const_iterator1 it1_end (boost::numeric::ublas::end (it2, iterator2_tag ()));
+#endif
+            while (it1 != it1_end) {
+                v (it1.index1 ()) += *it1 * e2 () (index2);
+                ++ it1;
+            }
+            ++ it2;
+        }
+        return v;
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const vector_expression<E2> &e2,
+               V &v, sparse_bidirectional_iterator_tag) {
+        typedef const E2 expression2_type;
+
+        typename expression2_type::const_iterator it (e2 ().begin ());
+        typename expression2_type::const_iterator it_end (e2 ().end ());
+        while (it != it_end) {
+            v.plus_assign (column (e1 (), it.index ()) * *it);
+            ++ it;
+        }
+        return v;
+    }
+
+    // Dispatcher
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const vector_expression<E2> &e2,
+               V &v, packed_random_access_iterator_tag) {
+        typedef typename E1::orientation_category orientation_category;
+        return axpy_prod (e1, e2, v, packed_random_access_iterator_tag (), orientation_category ());
+    }
+
+
+  /** \brief computes <tt>v += A x</tt> or <tt>v = A x</tt> in an
+          optimized fashion.
+
+          \param e1 the matrix expression \c A
+          \param e2 the vector expression \c x
+          \param v  the result vector \c v
+          \param init a boolean parameter
+
+          <tt>axpy_prod(A, x, v, init)</tt> implements the well known
+          axpy-product.  Setting \a init to \c true is equivalent to call
+          <tt>v.clear()</tt> before <tt>axpy_prod</tt>. Currently \a init
+          defaults to \c true, but this may change in the future.
+
+          Up to now there are some specialisation for compressed
+          matrices that give a large speed up compared to prod.
+          
+          \ingroup blas2
+
+          \internal
+          
+          template parameters:
+          \param V type of the result vector \c v
+          \param E1 type of a matrix expression \c A
+          \param E2 type of a vector expression \c x
+  */
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const vector_expression<E2> &e2,
+               V &v, bool init = true) {
+        typedef typename V::value_type value_type;
+        typedef typename E2::const_iterator::iterator_category iterator_category;
+
+        if (init)
+            v.assign (zero_vector<value_type> (e1 ().size1 ()));
+#if BOOST_UBLAS_TYPE_CHECK
+        vector<value_type> cv (v);
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
+        indexing_vector_assign<scalar_plus_assign> (cv, prod (e1, e2));
+#endif
+        axpy_prod (e1, e2, v, iterator_category ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
+#endif
+        return v;
+    }
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V
+    axpy_prod (const matrix_expression<E1> &e1,
+               const vector_expression<E2> &e2) {
+        typedef V vector_type;
+
+        vector_type v (e1 ().size1 ());
+        return axpy_prod (e1, e2, v, true);
+    }
+
+    template<class V, class E1, class T2, class IA2, class TA2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const vector_expression<E1> &e1,
+               const compressed_matrix<T2, column_major, 0, IA2, TA2> &e2,
+               V &v, column_major_tag) {
+        typedef typename V::size_type size_type;
+        typedef typename V::value_type value_type;
+
+        for (size_type j = 0; j < e2.filled1 () -1; ++ j) {
+            size_type begin = e2.index1_data () [j];
+            size_type end = e2.index1_data () [j + 1];
+            value_type t (v (j));
+            for (size_type i = begin; i < end; ++ i)
+                t += e2.value_data () [i] * e1 () (e2.index2_data () [i]);
+            v (j) = t;
+        }
+        return v;
+    }
+
+    template<class V, class E1, class T2, class IA2, class TA2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const vector_expression<E1> &e1,
+               const compressed_matrix<T2, row_major, 0, IA2, TA2> &e2,
+               V &v, row_major_tag) {
+        typedef typename V::size_type size_type;
+
+        for (size_type i = 0; i < e2.filled1 () -1; ++ i) {
+            size_type begin = e2.index1_data () [i];
+            size_type end = e2.index1_data () [i + 1];
+            for (size_type j = begin; j < end; ++ j)
+                v (e2.index2_data () [j]) += e2.value_data () [j] * e1 () (i);
+        }
+        return v;
+    }
+
+    // Dispatcher
+    template<class V, class E1, class T2, class L2, class IA2, class TA2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const vector_expression<E1> &e1,
+               const compressed_matrix<T2, L2, 0, IA2, TA2> &e2,
+               V &v, bool init = true) {
+        typedef typename V::value_type value_type;
+        typedef typename L2::orientation_category orientation_category;
+
+        if (init)
+            v.assign (zero_vector<value_type> (e2.size2 ()));
+#if BOOST_UBLAS_TYPE_CHECK
+        vector<value_type> cv (v);
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
+        indexing_vector_assign<scalar_plus_assign> (cv, prod (e1, e2));
+#endif
+        axpy_prod (e1, e2, v, orientation_category ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
+#endif
+        return v;
+    }
+    template<class V, class E1, class T2, class L2, class IA2, class TA2>
+    BOOST_UBLAS_INLINE
+    V
+    axpy_prod (const vector_expression<E1> &e1,
+               const compressed_matrix<T2, L2, 0, IA2, TA2> &e2) {
+        typedef V vector_type;
+
+        vector_type v (e2.size2 ());
+        return axpy_prod (e1, e2, v, true);
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const vector_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               V &v, packed_random_access_iterator_tag, column_major_tag) {
+        typedef const E2 expression2_type;
+        typedef typename V::size_type size_type;
+
+        typename expression2_type::const_iterator2 it2 (e2 ().begin2 ());
+        typename expression2_type::const_iterator2 it2_end (e2 ().end2 ());
+        while (it2 != it2_end) {
+            size_type index2 (it2.index2 ());
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename expression2_type::const_iterator1 it1 (it2.begin ());
+            typename expression2_type::const_iterator1 it1_end (it2.end ());
+#else
+            typename expression2_type::const_iterator1 it1 (boost::numeric::ublas::begin (it2, iterator2_tag ()));
+            typename expression2_type::const_iterator1 it1_end (boost::numeric::ublas::end (it2, iterator2_tag ()));
+#endif
+            while (it1 != it1_end) {
+                v (index2) += *it1 * e1 () (it1.index1 ());
+                ++ it1;
+            }
+            ++ it2;
+        }
+        return v;
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const vector_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               V &v, packed_random_access_iterator_tag, row_major_tag) {
+        typedef const E2 expression2_type;
+        typedef typename V::size_type size_type;
+
+        typename expression2_type::const_iterator1 it1 (e2 ().begin1 ());
+        typename expression2_type::const_iterator1 it1_end (e2 ().end1 ());
+        while (it1 != it1_end) {
+            size_type index1 (it1.index1 ());
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename expression2_type::const_iterator2 it2 (it1.begin ());
+            typename expression2_type::const_iterator2 it2_end (it1.end ());
+#else
+            typename expression2_type::const_iterator2 it2 (boost::numeric::ublas::begin (it1, iterator1_tag ()));
+            typename expression2_type::const_iterator2 it2_end (boost::numeric::ublas::end (it1, iterator1_tag ()));
+#endif
+            while (it2 != it2_end) {
+                v (it2.index2 ()) += *it2 * e1 () (index1);
+                ++ it2;
+            }
+            ++ it1;
+        }
+        return v;
+    }
+
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const vector_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               V &v, sparse_bidirectional_iterator_tag) {
+        typedef const E1 expression1_type;
+
+        typename expression1_type::const_iterator it (e1 ().begin ());
+        typename expression1_type::const_iterator it_end (e1 ().end ());
+        while (it != it_end) {
+            v.plus_assign (*it * row (e2 (), it.index ()));
+            ++ it;
+        }
+        return v;
+    }
+
+    // Dispatcher
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const vector_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               V &v, packed_random_access_iterator_tag) {
+        typedef typename E2::orientation_category orientation_category;
+        return axpy_prod (e1, e2, v, packed_random_access_iterator_tag (), orientation_category ());
+    }
+
+
+  /** \brief computes <tt>v += A<sup>T</sup> x</tt> or <tt>v = A<sup>T</sup> x</tt> in an
+          optimized fashion.
+
+          \param e1 the vector expression \c x
+          \param e2 the matrix expression \c A
+          \param v  the result vector \c v
+          \param init a boolean parameter
+
+          <tt>axpy_prod(x, A, v, init)</tt> implements the well known
+          axpy-product.  Setting \a init to \c true is equivalent to call
+          <tt>v.clear()</tt> before <tt>axpy_prod</tt>. Currently \a init
+          defaults to \c true, but this may change in the future.
+
+          Up to now there are some specialisation for compressed
+          matrices that give a large speed up compared to prod.
+          
+          \ingroup blas2
+
+          \internal
+          
+          template parameters:
+          \param V type of the result vector \c v
+          \param E1 type of a vector expression \c x
+          \param E2 type of a matrix expression \c A
+  */
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V &
+    axpy_prod (const vector_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               V &v, bool init = true) {
+        typedef typename V::value_type value_type;
+        typedef typename E1::const_iterator::iterator_category iterator_category;
+
+        if (init)
+            v.assign (zero_vector<value_type> (e2 ().size2 ()));
+#if BOOST_UBLAS_TYPE_CHECK
+        vector<value_type> cv (v);
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
+        indexing_vector_assign<scalar_plus_assign> (cv, prod (e1, e2));
+#endif
+        axpy_prod (e1, e2, v, iterator_category ());
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
+#endif
+        return v;
+    }
+    template<class V, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V
+    axpy_prod (const vector_expression<E1> &e1,
+               const matrix_expression<E2> &e2) {
+        typedef V vector_type;
+
+        vector_type v (e2 ().size2 ());
+        return axpy_prod (e1, e2, v, true);
+    }
+
+    template<class M, class E1, class E2, class TRI>
+    BOOST_UBLAS_INLINE
+    M &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               M &m, TRI,
+               dense_proxy_tag, row_major_tag) {
+
+        typedef typename M::size_type size_type;
+
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef typename M::value_type value_type;
+        matrix<value_type, row_major> cm (m);
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
+        indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), row_major_tag ());
+#endif
+        size_type size1 (e1 ().size1 ());
+        size_type size2 (e1 ().size2 ());
+        for (size_type i = 0; i < size1; ++ i)
+            for (size_type j = 0; j < size2; ++ j)
+                row (m, i).plus_assign (e1 () (i, j) * row (e2 (), j));
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
+#endif
+        return m;
+    }
+    template<class M, class E1, class E2, class TRI>
+    BOOST_UBLAS_INLINE
+    M &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               M &m, TRI,
+               sparse_proxy_tag, row_major_tag) {
+
+        typedef TRI triangular_restriction;
+        typedef const E1 expression1_type;
+        typedef const E2 expression2_type;
+
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef typename M::value_type value_type;
+        matrix<value_type, row_major> cm (m);
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
+        indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), row_major_tag ());
+#endif
+        typename expression1_type::const_iterator1 it1 (e1 ().begin1 ());
+        typename expression1_type::const_iterator1 it1_end (e1 ().end1 ());
+        while (it1 != it1_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename expression1_type::const_iterator2 it2 (it1.begin ());
+            typename expression1_type::const_iterator2 it2_end (it1.end ());
+#else
+            typename expression1_type::const_iterator2 it2 (boost::numeric::ublas::begin (it1, iterator1_tag ()));
+            typename expression1_type::const_iterator2 it2_end (boost::numeric::ublas::end (it1, iterator1_tag ()));
+#endif
+            while (it2 != it2_end) {
+                // row (m, it1.index1 ()).plus_assign (*it2 * row (e2 (), it2.index2 ()));
+                matrix_row<expression2_type> mr (e2 (), it2.index2 ());
+                typename matrix_row<expression2_type>::const_iterator itr (mr.begin ());
+                typename matrix_row<expression2_type>::const_iterator itr_end (mr.end ());
+                while (itr != itr_end) {
+                    if (triangular_restriction::other (it1.index1 (), itr.index ()))
+                        m (it1.index1 (), itr.index ()) += *it2 * *itr;
+                    ++ itr;
+                }
+                ++ it2;
+            }
+            ++ it1;
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
+#endif
+        return m;
+    }
+
+    template<class M, class E1, class E2, class TRI>
+    BOOST_UBLAS_INLINE
+    M &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               M &m, TRI,
+               dense_proxy_tag, column_major_tag) {
+        typedef typename M::size_type size_type;
+
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef typename M::value_type value_type;
+        matrix<value_type, column_major> cm (m);
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
+        indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), column_major_tag ());
+#endif
+        size_type size1 (e2 ().size1 ());
+        size_type size2 (e2 ().size2 ());
+        for (size_type j = 0; j < size2; ++ j)
+            for (size_type i = 0; i < size1; ++ i)
+                column (m, j).plus_assign (e2 () (i, j) * column (e1 (), i));
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
+#endif
+        return m;
+    }
+    template<class M, class E1, class E2, class TRI>
+    BOOST_UBLAS_INLINE
+    M &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               M &m, TRI,
+               sparse_proxy_tag, column_major_tag) {
+        typedef TRI triangular_restriction;
+        typedef const E1 expression1_type;
+        typedef const E2 expression2_type;
+
+
+#if BOOST_UBLAS_TYPE_CHECK
+        typedef typename M::value_type value_type;
+        matrix<value_type, column_major> cm (m);
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
+        indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), column_major_tag ());
+#endif
+        typename expression2_type::const_iterator2 it2 (e2 ().begin2 ());
+        typename expression2_type::const_iterator2 it2_end (e2 ().end2 ());
+        while (it2 != it2_end) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename expression2_type::const_iterator1 it1 (it2.begin ());
+            typename expression2_type::const_iterator1 it1_end (it2.end ());
+#else
+            typename expression2_type::const_iterator1 it1 (boost::numeric::ublas::begin (it2, iterator2_tag ()));
+            typename expression2_type::const_iterator1 it1_end (boost::numeric::ublas::end (it2, iterator2_tag ()));
+#endif
+            while (it1 != it1_end) {
+                // column (m, it2.index2 ()).plus_assign (*it1 * column (e1 (), it1.index1 ()));
+                matrix_column<expression1_type> mc (e1 (), it1.index1 ());
+                typename matrix_column<expression1_type>::const_iterator itc (mc.begin ());
+                typename matrix_column<expression1_type>::const_iterator itc_end (mc.end ());
+                while (itc != itc_end) {
+                    if(triangular_restriction::other (itc.index (), it2.index2 ()))
+                       m (itc.index (), it2.index2 ()) += *it1 * *itc;
+                    ++ itc;
+                }
+                ++ it1;
+            }
+            ++ it2;
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
+#endif
+        return m;
+    }
+
+    // Dispatcher
+    template<class M, class E1, class E2, class TRI>
+    BOOST_UBLAS_INLINE
+    M &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               M &m, TRI, bool init = true) {
+        typedef typename M::value_type value_type;
+        typedef typename M::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+        typedef TRI triangular_restriction;
+
+        if (init)
+            m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
+        return axpy_prod (e1, e2, m, triangular_restriction (), storage_category (), orientation_category ());
+    }
+    template<class M, class E1, class E2, class TRI>
+    BOOST_UBLAS_INLINE
+    M
+    axpy_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               TRI) {
+        typedef M matrix_type;
+        typedef TRI triangular_restriction;
+
+        matrix_type m (e1 ().size1 (), e2 ().size2 ());
+        return axpy_prod (e1, e2, m, triangular_restriction (), true);
+    }
+
+  /** \brief computes <tt>M += A X</tt> or <tt>M = A X</tt> in an
+          optimized fashion.
+
+          \param e1 the matrix expression \c A
+          \param e2 the matrix expression \c X
+          \param m  the result matrix \c M
+          \param init a boolean parameter
+
+          <tt>axpy_prod(A, X, M, init)</tt> implements the well known
+          axpy-product.  Setting \a init to \c true is equivalent to call
+          <tt>M.clear()</tt> before <tt>axpy_prod</tt>. Currently \a init
+          defaults to \c true, but this may change in the future.
+
+          Up to now there are no specialisations.
+          
+          \ingroup blas3
+
+          \internal
+          
+          template parameters:
+          \param M type of the result matrix \c M
+          \param E1 type of a matrix expression \c A
+          \param E2 type of a matrix expression \c X
+  */
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M &
+    axpy_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2,
+               M &m, bool init = true) {
+        typedef typename M::value_type value_type;
+        typedef typename M::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+
+        if (init)
+            m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
+        return axpy_prod (e1, e2, m, full (), storage_category (), orientation_category ());
+    }
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M
+    axpy_prod (const matrix_expression<E1> &e1,
+               const matrix_expression<E2> &e2) {
+        typedef M matrix_type;
+
+        matrix_type m (e1 ().size1 (), e2 ().size2 ());
+        return axpy_prod (e1, e2, m, full (), true);
+    }
+
+
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M &
+    opb_prod (const matrix_expression<E1> &e1,
+              const matrix_expression<E2> &e2,
+              M &m,
+              dense_proxy_tag, row_major_tag) {
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+
+#if BOOST_UBLAS_TYPE_CHECK
+        matrix<value_type, row_major> cm (m);
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
+        indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), row_major_tag ());
+#endif
+        size_type size (BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ()));
+        for (size_type k = 0; k < size; ++ k) {
+            vector<value_type> ce1 (column (e1 (), k));
+            vector<value_type> re2 (row (e2 (), k));
+            m.plus_assign (outer_prod (ce1, re2));
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
+#endif
+        return m;
+    }
+
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M &
+    opb_prod (const matrix_expression<E1> &e1,
+              const matrix_expression<E2> &e2,
+              M &m,
+              dense_proxy_tag, column_major_tag) {
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+
+#if BOOST_UBLAS_TYPE_CHECK
+        matrix<value_type, column_major> cm (m);
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
+        indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), column_major_tag ());
+#endif
+        size_type size (BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ()));
+        for (size_type k = 0; k < size; ++ k) {
+            vector<value_type> ce1 (column (e1 (), k));
+            vector<value_type> re2 (row (e2 (), k));
+            m.plus_assign (outer_prod (ce1, re2));
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
+#endif
+        return m;
+    }
+
+    // Dispatcher
+
+  /** \brief computes <tt>M += A X</tt> or <tt>M = A X</tt> in an
+          optimized fashion.
+
+          \param e1 the matrix expression \c A
+          \param e2 the matrix expression \c X
+          \param m  the result matrix \c M
+          \param init a boolean parameter
+
+          <tt>opb_prod(A, X, M, init)</tt> implements the well known
+          axpy-product. Setting \a init to \c true is equivalent to call
+          <tt>M.clear()</tt> before <tt>opb_prod</tt>. Currently \a init
+          defaults to \c true, but this may change in the future.
+
+          This function may give a speedup if \c A has less columns than
+          rows, because the product is computed as a sum of outer
+          products.
+          
+          \ingroup blas3
+
+          \internal
+          
+          template parameters:
+          \param M type of the result matrix \c M
+          \param E1 type of a matrix expression \c A
+          \param E2 type of a matrix expression \c X
+  */
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M &
+    opb_prod (const matrix_expression<E1> &e1,
+              const matrix_expression<E2> &e2,
+              M &m, bool init = true) {
+        typedef typename M::value_type value_type;
+        typedef typename M::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+
+        if (init)
+            m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
+        return opb_prod (e1, e2, m, storage_category (), orientation_category ());
+    }
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M
+    opb_prod (const matrix_expression<E1> &e1,
+              const matrix_expression<E2> &e2) {
+        typedef M matrix_type;
+
+        matrix_type m (e1 ().size1 (), e2 ().size2 ());
+        return opb_prod (e1, e2, m, true);
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/operation/begin.hpp b/include/boost/numeric/ublas/operation/begin.hpp
new file mode 100644
index 0000000..d14bb35
--- /dev/null
+++ b/include/boost/numeric/ublas/operation/begin.hpp
@@ -0,0 +1,318 @@
+/**
+ * -*- c++ -*-
+ *
+ * \file begin.hpp
+ *
+ * \brief The \c begin operation.
+ *
+ * Copyright (c) 2009, Marco Guazzone
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Marco Guazzone, marco.guazzone@gmail.com
+ */
+
+#ifndef BOOST_NUMERIC_UBLAS_OPERATION_BEGIN_HPP
+#define BOOST_NUMERIC_UBLAS_OPERATION_BEGIN_HPP
+
+
+#include <boost/numeric/ublas/expression_types.hpp>
+#include <boost/numeric/ublas/fwd.hpp>
+#include <boost/numeric/ublas/traits/const_iterator_type.hpp>
+#include <boost/numeric/ublas/traits/iterator_type.hpp>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    namespace detail {
+
+        /**
+         * \brief Auxiliary class for implementing the \c begin operation.
+         * \tparam CategoryT The expression category type (e.g., vector_tag).
+         * \tparam TagT The dimension type tag (e.g., tag::major).
+         * \tparam OrientationT The orientation category type (e.g., row_major_tag).
+         */
+        template <typename CategoryT, typename TagT=void, typename OrientationT=void>
+        struct begin_impl;
+
+
+        /// \brief Specialization of \c begin_impl for iterating vector expressions.
+        template <>
+        struct begin_impl<vector_tag,void,void>
+        {
+            /**
+             * \brief Return an iterator to the first element of the given vector
+             *  expression.
+             * \tparam ExprT A model of VectorExpression type.
+             * \param e A vector expression.
+             * \return An iterator over the given vector expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::iterator apply(ExprT& e)
+            {
+                return e.begin();
+            }
+
+
+            /**
+             * \brief Return a const iterator to the first element of the given vector
+             *  expression.
+             * \tparam ExprT A model of VectorExpression type.
+             * \param e A vector expression.
+             * \return A const iterator to the first element of the given vector
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::const_iterator apply(ExprT const& e)
+            {
+                return e.begin();
+            }
+        };
+
+
+        /// \brief Specialization of \c begin_impl for iterating matrix expressions with
+        ///  a row-major orientation over the major dimension.
+        template <>
+        struct begin_impl<matrix_tag,tag::major,row_major_tag>
+        {
+            /**
+             * \brief Return an iterator to the first element of the given row-major
+             *  matrix expression over the major dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return An iterator over the major dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::iterator1 apply(ExprT& e)
+            {
+                return e.begin1();
+            }
+
+
+            /**
+             * \brief Return a const iterator to the first element of the given
+             *  row-major matrix expression over the major dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return A const iterator over the major dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::const_iterator1 apply(ExprT const& e)
+            {
+                return e.begin1();
+            }
+        };
+
+
+        /// \brief Specialization of \c begin_impl for iterating matrix expressions with
+        ///  a column-major orientation over the major dimension.
+        template <>
+        struct begin_impl<matrix_tag,tag::major,column_major_tag>
+        {
+            /**
+             * \brief Return an iterator to the first element of the given column-major
+             *  matrix expression over the major dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return An iterator over the major dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::iterator2 apply(ExprT& e)
+            {
+                return e.begin2();
+            }
+
+
+            /**
+             * \brief Return a const iterator to the first element of the given
+             *  column-major matrix expression over the major dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return A const iterator over the major dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::const_iterator2 apply(ExprT const& e)
+            {
+                return e.begin2();
+            }
+        };
+
+
+        /// \brief Specialization of \c begin_impl for iterating matrix expressions with
+        ///  a row-major orientation over the minor dimension.
+        template <>
+        struct begin_impl<matrix_tag,tag::minor,row_major_tag>
+        {
+            /**
+             * \brief Return an iterator to the first element of the given row-major
+             *  matrix expression over the minor dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return An iterator over the minor dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::iterator2 apply(ExprT& e)
+            {
+                return e.begin2();
+            }
+
+
+            /**
+             * \brief Return a const iterator to the first element of the given
+             *  row-major matrix expression over the minor dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return A const iterator over the minor dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::const_iterator2 apply(ExprT const& e)
+            {
+                return e.begin2();
+            }
+        };
+
+
+
+        /// \brief Specialization of \c begin_impl for iterating matrix expressions with
+        ///  a column-major orientation over the minor dimension.
+        template <>
+        struct begin_impl<matrix_tag,tag::minor,column_major_tag>
+        {
+            /**
+             * \brief Return an iterator to the first element of the given column-major
+             *  matrix expression over the minor dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return An iterator over the minor dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::iterator1 apply(ExprT& e)
+            {
+                return e.begin1();
+            }
+
+
+            /**
+             * \brief Return a const iterator to the first element of the given
+             *  column-major matrix expression over the minor dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return A const iterator over the minor dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::const_iterator1 apply(ExprT const& e)
+            {
+                return e.begin1();
+            }
+        };
+
+    } // Namespace detail
+
+
+    /**
+     * \brief An iterator to the first element of the given vector expression.
+     * \tparam ExprT A model of VectorExpression type.
+     * \param e A vector expression.
+     * \return An iterator to the first element of the given vector expression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    typename ExprT::iterator begin(vector_expression<ExprT>& e)
+    {
+        return detail::begin_impl<typename ExprT::type_category>::apply(e());
+    }
+
+
+    /**
+     * \brief A const iterator to the first element of the given vector expression.
+     * \tparam ExprT A model of VectorExpression type.
+     * \param e A vector expression.
+     * \return A const iterator to the first element of the given vector expression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    typename ExprT::const_iterator begin(vector_expression<ExprT> const& e)
+    {
+        return detail::begin_impl<typename ExprT::type_category>::apply(e());
+    }
+
+
+    /**
+     * \brief An iterator to the first element of the given matrix expression
+     *  according to its orientation.
+     * \tparam DimTagT A dimension tag type (e.g., tag::major).
+     * \tparam ExprT A model of MatrixExpression type.
+     * \param e A matrix expression.
+     * \return An iterator to the first element of the given matrix expression
+     *  according to its orientation.
+     */
+    template <typename TagT, typename ExprT>
+    BOOST_UBLAS_INLINE
+    typename iterator_type<ExprT,TagT>::type begin(matrix_expression<ExprT>& e)
+    {
+        return detail::begin_impl<typename ExprT::type_category, TagT, typename ExprT::orientation_category>::apply(e());
+    }
+
+
+    /**
+     * \brief A const iterator to the first element of the given matrix expression
+     *  according to its orientation.
+     * \tparam TagT A dimension tag type (e.g., tag::major).
+     * \tparam ExprT A model of MatrixExpression type.
+     * \param e A matrix expression.
+     * \return A const iterator to the first element of the given matrix expression
+     *  according to its orientation.
+     */
+    template <typename TagT, typename ExprT>
+    BOOST_UBLAS_INLINE
+    typename const_iterator_type<ExprT,TagT>::type begin(matrix_expression<ExprT> const& e)
+    {
+        return detail::begin_impl<typename ExprT::type_category, TagT, typename ExprT::orientation_category>::apply(e());
+    }
+
+
+    /**
+     * \brief An iterator to the first element over the dual dimension of the given
+     *  iterator.
+     * \tparam IteratorT A model of Iterator type.
+     * \param it An iterator.
+     * \return An iterator to the first element over the dual dimension of the given
+     *  iterator.
+     */
+    template <typename IteratorT>
+    BOOST_UBLAS_INLINE
+    typename IteratorT::dual_iterator_type begin(IteratorT& it)
+    {
+        return it.begin();
+    }
+
+
+    /**
+     * \brief A const iterator to the first element over the dual dimension of the
+     *  given iterator.
+     * \tparam IteratorT A model of Iterator type.
+     * \param it An iterator.
+     * \return A const iterator to the first element over the dual dimension of the
+     *  given iterator.
+     */
+    template <typename IteratorT>
+    BOOST_UBLAS_INLINE
+    typename IteratorT::dual_iterator_type begin(IteratorT const& it)
+    {
+        return it.begin();
+    }
+
+}}} // Namespace boost::numeric::ublas
+
+
+#endif // BOOST_NUMERIC_UBLAS_OPERATION_BEGIN_HPP
diff --git a/include/boost/numeric/ublas/operation/c_array.hpp b/include/boost/numeric/ublas/operation/c_array.hpp
new file mode 100644
index 0000000..7b3aee0
--- /dev/null
+++ b/include/boost/numeric/ublas/operation/c_array.hpp
@@ -0,0 +1,41 @@
+/**
+ * -*- c++ -*-
+ *
+ * \file c_array.hpp
+ *
+ * \brief provides specializations of matrix and vector operations for c arrays and c matrices.
+ *
+ * Copyright (c) 2009, Gunter Winkler
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Gunter Winkler (guwi17 at gmx dot de)
+ */
+
+#ifndef BOOST_NUMERIC_UBLAS_OPERATION_C_ARRAY_HPP
+#define BOOST_NUMERIC_UBLAS_OPERATION_C_ARRAY_HPP
+
+#include <boost/numeric/ublas/traits/c_array.hpp>
+
+namespace boost { namespace numeric { namespace ublas {
+
+    namespace detail {
+
+    
+    
+    } // namespace boost::numeric::ublas::detail
+
+
+    template <typename T>
+    BOOST_UBLAS_INLINE
+    typename ExprT::const_iterator begin(vector_expression<ExprT> const& e)
+    {
+        return detail::begin_impl<typename ExprT::type_category>::apply(e());
+    }
+
+
+}}} // Namespace boost::numeric::ublas
+
+#endif
diff --git a/include/boost/numeric/ublas/operation/end.hpp b/include/boost/numeric/ublas/operation/end.hpp
new file mode 100644
index 0000000..2e3b3e5
--- /dev/null
+++ b/include/boost/numeric/ublas/operation/end.hpp
@@ -0,0 +1,318 @@
+/**
+ * -*- c++ -*-
+ *
+ * \file end.hpp
+ *
+ * \brief The \c end operation.
+ *
+ * Copyright (c) 2009, Marco Guazzone
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Marco Guazzone, marco.guazzone@gmail.com
+ */
+
+
+#ifndef BOOST_NUMERIC_UBLAS_OPERATION_END_HPP
+#define BOOST_NUMERIC_UBLAS_OPERATION_END_HPP
+
+
+#include <boost/numeric/ublas/expression_types.hpp>
+#include <boost/numeric/ublas/fwd.hpp>
+#include <boost/numeric/ublas/traits/const_iterator_type.hpp>
+#include <boost/numeric/ublas/traits/iterator_type.hpp>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    namespace detail {
+
+        /**
+         * \brief Auxiliary class for implementing the \c end operation.
+         * \tparam CategoryT The expression category type (e.g., vector_tag).
+         * \tparam TagT The dimension type tag (e.g., tag::major).
+         * \tparam OrientationT The orientation category type (e.g., row_major_tag).
+         */
+        template <typename CategoryT, typename TagT=void, typename OrientationT=void>
+        struct end_impl;
+
+
+        /// \brief Specialization of \c end_impl for iterating vector expressions.
+        template <>
+        struct end_impl<vector_tag,void,void>
+        {
+            /**
+             * \brief Return an iterator to the last element of the given vector
+             *  expression.
+             * \tparam ExprT A model of VectorExpression type.
+             * \param e A vector expression.
+             * \return An iterator over the given vector expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::iterator apply(ExprT& e)
+            {
+                return e.end();
+            }
+
+
+            /**
+             * \brief Return a const iterator to the last element of the given vector
+             *  expression.
+             * \tparam ExprT A model of VectorExpression type.
+             * \param e A vector expression.
+             * \return A const iterator to the first element of the given vector
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::const_iterator apply(ExprT const& e)
+            {
+                return e.end();
+            }
+        };
+
+
+        /// \brief Specialization of \c end_impl for iterating matrix expressions with a
+        ///  row-major orientation over the major dimension.
+        template <>
+        struct end_impl<matrix_tag,tag::major,row_major_tag>
+        {
+            /**
+             * \brief Return an iterator to the last element of the given row-major
+             *  matrix expression over the major dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return An iterator over the major dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::iterator1 apply(ExprT& e)
+            {
+                return e.end1();
+            }
+
+
+            /**
+             * \brief Return a const iterator to the last element of the given row-major
+             *  matrix expression over the major dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return A const iterator over the major dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::const_iterator1 apply(ExprT const& e)
+            {
+                return e.end1();
+            }
+        };
+
+
+        /// \brief Specialization of \c end_impl for iterating matrix expressions with a
+        ///  column-major orientation over the major dimension.
+        template <>
+        struct end_impl<matrix_tag,tag::major,column_major_tag>
+        {
+            /**
+             * \brief Return an iterator to the last element of the given column-major
+             *  matrix expression over the major dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return An iterator over the major dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::iterator2 apply(ExprT& e)
+            {
+                return e.end2();
+            }
+
+
+            /**
+             * \brief Return a const iterator to the last element of the given
+             *  column-major matrix expression over the major dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return A const iterator over the major dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::const_iterator2 apply(ExprT const& e)
+            {
+                return e.end2();
+            }
+        };
+
+
+        /// \brief Specialization of \c end_impl for iterating matrix expressions with a
+        ///  row-major orientation over the minor dimension.
+        template <>
+        struct end_impl<matrix_tag,tag::minor,row_major_tag>
+        {
+            /**
+             * \brief Return an iterator to the last element of the given row-major
+             *  matrix expression over the minor dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return An iterator over the minor dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::iterator2 apply(ExprT& e)
+            {
+                return e.end2();
+            }
+
+
+            /**
+             * \brief Return a const iterator to the last element of the given
+             *  row-minor matrix expression over the major dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return A const iterator over the minor dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::const_iterator2 apply(ExprT const& e)
+            {
+                return e.end2();
+            }
+        };
+
+
+        /// \brief Specialization of \c end_impl for iterating matrix expressions with a
+        ///  column-major orientation over the minor dimension.
+        template <>
+        struct end_impl<matrix_tag,tag::minor,column_major_tag>
+        {
+            /**
+             * \brief Return an iterator to the last element of the given column-major
+             *  matrix expression over the minor dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return An iterator over the minor dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::iterator1 apply(ExprT& e)
+            {
+                return e.end1();
+            }
+
+
+            /**
+             * \brief Return a const iterator to the last element of the given
+             *  column-minor matrix expression over the major dimension.
+             * \tparam ExprT A model of MatrixExpression type.
+             * \param e A matrix expression.
+             * \return A const iterator over the minor dimension of the given matrix
+             *  expression.
+             */
+            template <typename ExprT>
+            static typename ExprT::const_iterator1 apply(ExprT const& e)
+            {
+                return e.end1();
+            }
+        };
+
+    } // Namespace detail
+
+
+    /**
+     * \brief An iterator to the last element of the given vector expression.
+     * \tparam ExprT A model of VectorExpression type.
+     * \param e A vector expression.
+     * \return An iterator to the last element of the given vector expression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    typename ExprT::iterator end(vector_expression<ExprT>& e)
+    {
+        return detail::end_impl<typename ExprT::type_category>::apply(e());
+    }
+
+
+    /**
+     * \brief A const iterator to the last element of the given vector expression.
+     * \tparam ExprT A model of VectorExpression type.
+     * \param e A vector expression.
+     * \return A const iterator to the last element of the given vector expression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    typename ExprT::const_iterator end(vector_expression<ExprT> const& e)
+    {
+        return detail::end_impl<typename ExprT::type_category>::apply(e());
+    }
+
+
+    /**
+     * \brief An iterator to the last element of the given matrix expression
+     *  according to its orientation.
+     * \tparam DimTagT A dimension tag type (e.g., tag::major).
+     * \tparam ExprT A model of MatrixExpression type.
+     * \param e A matrix expression.
+     * \return An iterator to the last element of the given matrix expression
+     *  according to its orientation.
+     */
+    template <typename TagT, typename ExprT>
+    BOOST_UBLAS_INLINE
+    typename iterator_type<ExprT,TagT>::type end(matrix_expression<ExprT>& e)
+    {
+        return detail::end_impl<typename ExprT::type_category, TagT, typename ExprT::orientation_category>::apply(e());
+    }
+
+
+    /**
+     * \brief A const iterator to the last element of the given matrix expression
+     *  according to its orientation.
+     * \tparam TagT A dimension tag type (e.g., tag::major).
+     * \tparam ExprT A model of MatrixExpression type.
+     * \param e A matrix expression.
+     * \return A const iterator to the last element of the given matrix expression
+     *  according to its orientation.
+     */
+    template <typename TagT, typename ExprT>
+    BOOST_UBLAS_INLINE
+    typename const_iterator_type<ExprT,TagT>::type end(matrix_expression<ExprT> const& e)
+    {
+        return detail::end_impl<typename ExprT::type_category, TagT, typename ExprT::orientation_category>::apply(e());
+    }
+
+
+    /**
+     * \brief An iterator to the last element over the dual dimension of the given
+     *  iterator.
+     * \tparam IteratorT A model of Iterator type.
+     * \param it An iterator.
+     * \return An iterator to the last element over the dual dimension of the given
+     *  iterator.
+     */
+    template <typename IteratorT>
+    BOOST_UBLAS_INLINE
+    typename IteratorT::dual_iterator_type end(IteratorT& it)
+    {
+        return it.end();
+    }
+
+
+    /**
+     * \brief A const iterator to the last element over the dual dimension of the
+     *  given iterator.
+     * \tparam IteratorT A model of Iterator type.
+     * \param it An iterator.
+     * \return A const iterator to the last element over the dual dimension of the
+     *  given iterator.
+     */
+    template <typename IteratorT>
+    BOOST_UBLAS_INLINE
+    typename IteratorT::dual_iterator_type end(IteratorT const& it)
+    {
+        return it.end();
+    }
+
+}}} // Namespace boost::numeric::ublas
+
+
+#endif // BOOST_NUMERIC_UBLAS_OPERATION_END_HPP
diff --git a/include/boost/numeric/ublas/operation/num_columns.hpp b/include/boost/numeric/ublas/operation/num_columns.hpp
new file mode 100644
index 0000000..ee48eea
--- /dev/null
+++ b/include/boost/numeric/ublas/operation/num_columns.hpp
@@ -0,0 +1,45 @@
+/**
+ * -*- c++ -*-
+ *
+ * \file num_columns.hpp
+ *
+ * \brief The \c num_columns operation.
+ *
+ * Copyright (c) 2009, Marco Guazzone
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Marco Guazzone, marco.guazzone@gmail.com
+ */
+
+
+#ifndef BOOST_NUMERIC_UBLAS_OPERATION_NUM_COLUMNS_HPP
+#define BOOST_NUMERIC_UBLAS_OPERATION_NUM_COLUMNS_HPP
+
+
+#include <boost/numeric/ublas/detail/config.hpp>
+#include <boost/numeric/ublas/expression_types.hpp>
+#include <boost/numeric/ublas/traits.hpp>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    /**
+     * \brief Return the number of columns.
+     * \tparam MatrixExprT A type which models the matrix expression concept.
+     * \param m A matrix expression.
+     * \return The number of columns.
+     */
+    template <typename MatrixExprT>
+    BOOST_UBLAS_INLINE
+    typename matrix_traits<MatrixExprT>::size_type num_columns(matrix_expression<MatrixExprT> const& me)
+    {
+        return me().size2();
+    }
+
+}}} // Namespace boost::numeric::ublas
+
+
+#endif // BOOST_NUMERIC_UBLAS_OPERATION_NUM_COLUMNS_HPP
diff --git a/include/boost/numeric/ublas/operation/num_rows.hpp b/include/boost/numeric/ublas/operation/num_rows.hpp
new file mode 100644
index 0000000..246aed3
--- /dev/null
+++ b/include/boost/numeric/ublas/operation/num_rows.hpp
@@ -0,0 +1,44 @@
+/**
+ * -*- c++ -*-
+ *
+ * \file num_rows.hpp
+ *
+ * \brief The \c num_rows operation.
+ *
+ * Copyright (c) 2009-2012, Marco Guazzone
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Marco Guazzone, marco.guazzone@gmail.com
+ */
+
+#ifndef BOOST_NUMERIC_UBLAS_OPERATION_NUM_ROWS_HPP
+#define BOOST_NUMERIC_UBLAS_OPERATION_NUM_ROWS_HPP
+
+
+#include <boost/numeric/ublas/detail/config.hpp>
+#include <boost/numeric/ublas/expression_types.hpp>
+#include <boost/numeric/ublas/traits.hpp>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    /**
+     * \brief Return the number of rows.
+     * \tparam MatrixExprT A type which models the matrix expression concept.
+     * \param m A matrix expression.
+     * \return The number of rows.
+     */
+    template <typename MatrixExprT>
+    BOOST_UBLAS_INLINE
+    typename matrix_traits<MatrixExprT>::size_type num_rows(matrix_expression<MatrixExprT> const& me)
+    {
+        return me().size1();
+    }
+
+}}} // Namespace boost::numeric::ublas
+
+
+#endif // BOOST_NUMERIC_UBLAS_OPERATION_NUM_ROWS_HPP
diff --git a/include/boost/numeric/ublas/operation/size.hpp b/include/boost/numeric/ublas/operation/size.hpp
new file mode 100644
index 0000000..b42090a
--- /dev/null
+++ b/include/boost/numeric/ublas/operation/size.hpp
@@ -0,0 +1,350 @@
+/**
+ * \file size.hpp
+ *
+ * \brief The family of \c size operations.
+ *
+ * Copyright (c) 2009-2010, Marco Guazzone
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Marco Guazzone, marco.guazzone@gmail.com
+ */
+
+#ifndef BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP
+#define BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP
+
+
+#include <boost/mpl/has_xxx.hpp> 
+#include <boost/mpl/if.hpp>
+#include <boost/numeric/ublas/detail/config.hpp>
+#include <boost/numeric/ublas/expression_types.hpp>
+#include <boost/numeric/ublas/fwd.hpp>
+#include <boost/numeric/ublas/tags.hpp>
+#include <boost/numeric/ublas/traits.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <cstddef>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+namespace detail { namespace /*<unnamed>*/ {
+
+/// Define a \c has_size_type trait class.
+BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
+
+
+/**
+ * \brief Wrapper type-traits used in \c boost::lazy_enabled_if for getting the
+ *  size type (see below).
+ * \tparam VectorT A vector type.
+ */
+template <typename VectorT>
+struct vector_size_type
+{
+    /// The size type.
+    typedef typename vector_traits<VectorT>::size_type type;
+};
+
+/**
+ * \brief Wrapper type-traits used in \c boost::lazy_enabled_if for getting the
+ *  size type (see below).
+ * \tparam MatrixT A matrix type.
+ */
+template <typename MatrixT>
+struct matrix_size_type
+{
+    /// The size type.
+    typedef typename matrix_traits<MatrixT>::size_type type;
+};
+
+
+/**
+ * \brief Auxiliary class for computing the size of the given dimension for
+ *  a container of the given category.
+ * \tparam Dim The dimension number (starting from 1).
+ * \tparam CategoryT The category type (e.g., vector_tag).
+ */
+template <std::size_t Dim, typename CategoryT>
+struct size_by_dim_impl;
+
+
+/**
+ * \brief Auxiliary class for computing the size of the given dimension for
+ *  a container of the given category and with the given orientation.
+ * \tparam Dim The dimension number (starting from 1).
+ * \tparam CategoryT The category type (e.g., vector_tag).
+ * \tparam OrientationT The orientation category type (e.g., row_major_tag).
+ */
+template <typename TagT, typename CategoryT, typename OrientationT>
+struct size_by_tag_impl;
+
+
+/**
+ * \brief Specialization of \c size_by_dim_impl for computing the size of a
+ *  vector.
+ */
+template <>
+struct size_by_dim_impl<1, vector_tag>
+{
+    /**
+     * \brief Compute the size of the given vector.
+     * \tparam ExprT A vector expression type.
+     * \pre ExprT must be a model of VectorExpression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    static typename vector_traits<ExprT>::size_type apply(vector_expression<ExprT> const& ve)
+    {
+        return ve().size();
+    }
+};
+
+
+/**
+ * \brief Specialization of \c size_by_dim_impl for computing the number of
+ *  rows of a matrix
+ */
+template <>
+struct size_by_dim_impl<1, matrix_tag>
+{
+    /**
+     * \brief Compute the number of rows of the given matrix.
+     * \tparam ExprT A matrix expression type.
+     * \pre ExprT must be a model of MatrixExpression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
+    {
+        return me().size1();
+    }
+};
+
+
+/**
+ * \brief Specialization of \c size_by_dim_impl for computing the number of
+ *  columns of a matrix
+ */
+template <>
+struct size_by_dim_impl<2, matrix_tag>
+{
+    /**
+     * \brief Compute the number of columns of the given matrix.
+     * \tparam ExprT A matrix expression type.
+     * \pre ExprT must be a model of MatrixExpression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
+    {
+        return me().size2();
+    }
+};
+
+
+/**
+ * \brief Specialization of \c size_by_tag_impl for computing the size of the
+ *  major dimension of a row-major oriented matrix.
+ */
+template <>
+struct size_by_tag_impl<tag::major, matrix_tag, row_major_tag>
+{
+    /**
+     * \brief Compute the number of rows of the given matrix.
+     * \tparam ExprT A matrix expression type.
+     * \pre ExprT must be a model of MatrixExpression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
+    {
+        return me().size1();
+    }
+};
+
+
+/**
+ * \brief Specialization of \c size_by_tag_impl for computing the size of the
+ *  minor dimension of a row-major oriented matrix.
+ */
+template <>
+struct size_by_tag_impl<tag::minor, matrix_tag, row_major_tag>
+{
+    /**
+     * \brief Compute the number of columns of the given matrix.
+     * \tparam ExprT A matrix expression type.
+     * \pre ExprT must be a model of MatrixExpression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
+    {
+        return me().size2();
+    }
+};
+
+
+/**
+ * \brief Specialization of \c size_by_tag_impl for computing the size of the
+ *  leading dimension of a row-major oriented matrix.
+ */
+template <>
+struct size_by_tag_impl<tag::leading, matrix_tag, row_major_tag>
+{
+    /**
+     * \brief Compute the number of columns of the given matrix.
+     * \tparam ExprT A matrix expression type.
+     * \pre ExprT must be a model of MatrixExpression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
+    {
+        return me().size2();
+    }
+};
+
+
+/// \brief Specialization of \c size_by_tag_impl for computing the size of the
+///  major dimension of a column-major oriented matrix.
+template <>
+struct size_by_tag_impl<tag::major, matrix_tag, column_major_tag>
+{
+    /**
+     * \brief Compute the number of columns of the given matrix.
+     * \tparam ExprT A matrix expression type.
+     * \pre ExprT must be a model of MatrixExpression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
+    {
+        return me().size2();
+    }
+};
+
+
+/// \brief Specialization of \c size_by_tag_impl for computing the size of the
+///  minor dimension of a column-major oriented matrix.
+template <>
+struct size_by_tag_impl<tag::minor, matrix_tag, column_major_tag>
+{
+    /**
+     * \brief Compute the number of rows of the given matrix.
+     * \tparam ExprT A matrix expression type.
+     * \pre ExprT must be a model of MatrixExpression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
+    {
+        return me().size1();
+    }
+};
+
+
+/// \brief Specialization of \c size_by_tag_impl for computing the size of the
+///  leading dimension of a column-major oriented matrix.
+template <>
+struct size_by_tag_impl<tag::leading, matrix_tag, column_major_tag>
+{
+    /**
+     * \brief Compute the number of rows of the given matrix.
+     * \tparam ExprT A matrix expression type.
+     * \pre ExprT must be a model of MatrixExpression.
+     */
+    template <typename ExprT>
+    BOOST_UBLAS_INLINE
+    static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
+    {
+        return me().size1();
+    }
+};
+
+
+/// \brief Specialization of \c size_by_tag_impl for computing the size of the
+///  given dimension of a unknown oriented expression.
+template <typename TagT, typename CategoryT>
+struct size_by_tag_impl<TagT, CategoryT, unknown_orientation_tag>: size_by_tag_impl<TagT, CategoryT, row_major_tag>
+{
+    // Empty
+};
+
+}} // Namespace detail::<unnamed>
+
+
+/**
+ * \brief Return the number of columns.
+ * \tparam VectorExprT A type which models the vector expression concept.
+ * \param ve A vector expression.
+ * \return The length of the input vector expression.
+ */
+template <typename VectorExprT>
+BOOST_UBLAS_INLINE
+typename ::boost::lazy_enable_if_c<
+    detail::has_size_type<VectorExprT>::value,
+    detail::vector_size_type<VectorExprT>
+>::type size(vector_expression<VectorExprT> const& ve)
+{
+    return ve().size();
+}
+
+
+/**
+ * \brief Return the size of the given dimension for the given vector
+ *  expression.
+ * \tparam Dim The dimension number (starting from 1).
+ * \tparam VectorExprT A vector expression type.
+ * \param ve A vector expression.
+ * \return The length of the input vector expression.
+ */
+template <std::size_t Dim, typename VectorExprT>
+BOOST_UBLAS_INLINE
+typename vector_traits<VectorExprT>::size_type size(vector_expression<VectorExprT> const& ve)
+{
+    return detail::size_by_dim_impl<Dim, vector_tag>::apply(ve);
+}
+
+
+/**
+ * \brief Return the size of the given dimension for the given matrix
+ *  expression.
+ * \tparam Dim The dimension number (starting from 1).
+ * \tparam MatrixExprT A matrix expression type.
+ * \param e A matrix expression.
+ * \return The size of the input matrix expression associated to the dimension
+ *  \a Dim.
+ */
+template <std::size_t Dim, typename MatrixExprT>
+BOOST_UBLAS_INLINE
+typename matrix_traits<MatrixExprT>::size_type size(matrix_expression<MatrixExprT> const& me)
+{
+    return detail::size_by_dim_impl<Dim, matrix_tag>::apply(me);
+}
+
+
+/**
+ * \brief Return the size of the given dimension tag for the given matrix
+ *  expression.
+ * \tparam TagT The dimension tag type (e.g., tag::major).
+ * \tparam MatrixExprT A matrix expression type.
+ * \param e A matrix expression.
+ * \return The size of the input matrix expression associated to the dimension
+ *  tag \a TagT.
+ */
+template <typename TagT, typename MatrixExprT>
+BOOST_UBLAS_INLINE
+typename ::boost::lazy_enable_if_c<
+    detail::has_size_type<MatrixExprT>::value,
+    detail::matrix_size_type<MatrixExprT>
+>::type size(matrix_expression<MatrixExprT> const& me)
+{
+    return detail::size_by_tag_impl<TagT, matrix_tag, typename matrix_traits<MatrixExprT>::orientation_category>::apply(me);
+}
+
+}}} // Namespace boost::numeric::ublas
+
+
+#endif // BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP
diff --git a/include/boost/numeric/ublas/operation_blocked.hpp b/include/boost/numeric/ublas/operation_blocked.hpp
new file mode 100644
index 0000000..812b24e
--- /dev/null
+++ b/include/boost/numeric/ublas/operation_blocked.hpp
@@ -0,0 +1,266 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_OPERATION_BLOCKED_
+#define _BOOST_UBLAS_OPERATION_BLOCKED_
+
+#include <boost/numeric/ublas/traits.hpp>
+#include <boost/numeric/ublas/detail/vector_assign.hpp> // indexing_vector_assign
+#include <boost/numeric/ublas/detail/matrix_assign.hpp> // indexing_matrix_assign
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    template<class V, typename V::size_type BS, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V
+    block_prod (const matrix_expression<E1> &e1,
+                const vector_expression<E2> &e2) {
+        typedef V vector_type;
+        typedef const E1 expression1_type;
+        typedef const E2 expression2_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::value_type value_type;
+        const size_type block_size = BS;
+
+        V v (e1 ().size1 ());
+#if BOOST_UBLAS_TYPE_CHECK
+        vector<value_type> cv (v.size ());
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
+        indexing_vector_assign<scalar_assign> (cv, prod (e1, e2));
+#endif
+        size_type i_size = e1 ().size1 ();
+        size_type j_size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size ());
+        for (size_type i_begin = 0; i_begin < i_size; i_begin += block_size) {
+            size_type i_end = i_begin + (std::min) (i_size - i_begin, block_size);
+            // FIX: never ignore Martin Weiser's advice ;-(
+#ifdef BOOST_UBLAS_NO_CACHE
+            vector_range<vector_type> v_range (v, range (i_begin, i_end));
+#else
+            // vector<value_type, bounded_array<value_type, block_size> > v_range (i_end - i_begin);
+            vector<value_type> v_range (i_end - i_begin);
+#endif
+            v_range.assign (zero_vector<value_type> (i_end - i_begin));
+            for (size_type j_begin = 0; j_begin < j_size; j_begin += block_size) {
+                size_type j_end = j_begin + (std::min) (j_size - j_begin, block_size);
+#ifdef BOOST_UBLAS_NO_CACHE
+                const matrix_range<expression1_type> e1_range (e1 (), range (i_begin, i_end), range (j_begin, j_end));
+                const vector_range<expression2_type> e2_range (e2 (), range (j_begin, j_end));
+                v_range.plus_assign (prod (e1_range, e2_range));
+#else
+                // const matrix<value_type, row_major, bounded_array<value_type, block_size * block_size> > e1_range (project (e1 (), range (i_begin, i_end), range (j_begin, j_end)));
+                // const vector<value_type, bounded_array<value_type, block_size> > e2_range (project (e2 (), range (j_begin, j_end)));
+                const matrix<value_type, row_major> e1_range (project (e1 (), range (i_begin, i_end), range (j_begin, j_end)));
+                const vector<value_type> e2_range (project (e2 (), range (j_begin, j_end)));
+                v_range.plus_assign (prod (e1_range, e2_range));
+#endif
+            }
+#ifndef BOOST_UBLAS_NO_CACHE
+            project (v, range (i_begin, i_end)).assign (v_range);
+#endif
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
+#endif
+        return v;
+    }
+
+    template<class V, typename V::size_type BS, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    V
+    block_prod (const vector_expression<E1> &e1,
+                const matrix_expression<E2> &e2) {
+        typedef V vector_type;
+        typedef const E1 expression1_type;
+        typedef const E2 expression2_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::value_type value_type;
+        const size_type block_size = BS;
+
+        V v (e2 ().size2 ());
+#if BOOST_UBLAS_TYPE_CHECK
+        vector<value_type> cv (v.size ());
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
+        indexing_vector_assign<scalar_assign> (cv, prod (e1, e2));
+#endif
+        size_type i_size = BOOST_UBLAS_SAME (e1 ().size (), e2 ().size1 ());
+        size_type j_size = e2 ().size2 ();
+        for (size_type j_begin = 0; j_begin < j_size; j_begin += block_size) {
+            size_type j_end = j_begin + (std::min) (j_size - j_begin, block_size);
+            // FIX: never ignore Martin Weiser's advice ;-(
+#ifdef BOOST_UBLAS_NO_CACHE
+            vector_range<vector_type> v_range (v, range (j_begin, j_end));
+#else
+            // vector<value_type, bounded_array<value_type, block_size> > v_range (j_end - j_begin);
+            vector<value_type> v_range (j_end - j_begin);
+#endif
+            v_range.assign (zero_vector<value_type> (j_end - j_begin));
+            for (size_type i_begin = 0; i_begin < i_size; i_begin += block_size) {
+                size_type i_end = i_begin + (std::min) (i_size - i_begin, block_size);
+#ifdef BOOST_UBLAS_NO_CACHE
+                const vector_range<expression1_type> e1_range (e1 (), range (i_begin, i_end));
+                const matrix_range<expression2_type> e2_range (e2 (), range (i_begin, i_end), range (j_begin, j_end));
+#else
+                // const vector<value_type, bounded_array<value_type, block_size> > e1_range (project (e1 (), range (i_begin, i_end)));
+                // const matrix<value_type, column_major, bounded_array<value_type, block_size * block_size> > e2_range (project (e2 (), range (i_begin, i_end), range (j_begin, j_end)));
+                const vector<value_type> e1_range (project (e1 (), range (i_begin, i_end)));
+                const matrix<value_type, column_major> e2_range (project (e2 (), range (i_begin, i_end), range (j_begin, j_end)));
+#endif
+                v_range.plus_assign (prod (e1_range, e2_range));
+            }
+#ifndef BOOST_UBLAS_NO_CACHE
+            project (v, range (j_begin, j_end)).assign (v_range);
+#endif
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
+#endif
+        return v;
+    }
+
+    template<class M, typename M::size_type BS, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M
+    block_prod (const matrix_expression<E1> &e1,
+                const matrix_expression<E2> &e2,
+                row_major_tag) {
+        typedef M matrix_type;
+        typedef const E1 expression1_type;
+        typedef const E2 expression2_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+        const size_type block_size = BS;
+
+        M m (e1 ().size1 (), e2 ().size2 ());
+#if BOOST_UBLAS_TYPE_CHECK
+        matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
+        indexing_matrix_assign<scalar_assign> (cm, prod (e1, e2), row_major_tag ());
+        disable_type_check<bool>::value = true;
+#endif
+        size_type i_size = e1 ().size1 ();
+        size_type j_size = e2 ().size2 ();
+        size_type k_size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ());
+        for (size_type i_begin = 0; i_begin < i_size; i_begin += block_size) {
+            size_type i_end = i_begin + (std::min) (i_size - i_begin, block_size);
+            for (size_type j_begin = 0; j_begin < j_size; j_begin += block_size) {
+                size_type j_end = j_begin + (std::min) (j_size - j_begin, block_size);
+                // FIX: never ignore Martin Weiser's advice ;-(
+#ifdef BOOST_UBLAS_NO_CACHE
+                matrix_range<matrix_type> m_range (m, range (i_begin, i_end), range (j_begin, j_end));
+#else
+                // matrix<value_type, row_major, bounded_array<value_type, block_size * block_size> > m_range (i_end - i_begin, j_end - j_begin);
+                matrix<value_type, row_major> m_range (i_end - i_begin, j_end - j_begin);
+#endif
+                m_range.assign (zero_matrix<value_type> (i_end - i_begin, j_end - j_begin));
+                for (size_type k_begin = 0; k_begin < k_size; k_begin += block_size) {
+                    size_type k_end = k_begin + (std::min) (k_size - k_begin, block_size);
+#ifdef BOOST_UBLAS_NO_CACHE
+                    const matrix_range<expression1_type> e1_range (e1 (), range (i_begin, i_end), range (k_begin, k_end));
+                    const matrix_range<expression2_type> e2_range (e2 (), range (k_begin, k_end), range (j_begin, j_end));
+#else
+                    // const matrix<value_type, row_major, bounded_array<value_type, block_size * block_size> > e1_range (project (e1 (), range (i_begin, i_end), range (k_begin, k_end)));
+                    // const matrix<value_type, column_major, bounded_array<value_type, block_size * block_size> > e2_range (project (e2 (), range (k_begin, k_end), range (j_begin, j_end)));
+                    const matrix<value_type, row_major> e1_range (project (e1 (), range (i_begin, i_end), range (k_begin, k_end)));
+                    const matrix<value_type, column_major> e2_range (project (e2 (), range (k_begin, k_end), range (j_begin, j_end)));
+#endif
+                    m_range.plus_assign (prod (e1_range, e2_range));
+                }
+#ifndef BOOST_UBLAS_NO_CACHE
+                project (m, range (i_begin, i_end), range (j_begin, j_end)).assign (m_range);
+#endif
+            }
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        disable_type_check<bool>::value = false;
+        BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
+#endif
+        return m;
+    }
+
+    template<class M, typename M::size_type BS, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M
+    block_prod (const matrix_expression<E1> &e1,
+                const matrix_expression<E2> &e2,
+                column_major_tag) {
+        typedef M matrix_type;
+        typedef const E1 expression1_type;
+        typedef const E2 expression2_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+        const size_type block_size = BS;
+
+        M m (e1 ().size1 (), e2 ().size2 ());
+#if BOOST_UBLAS_TYPE_CHECK
+        matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
+        typedef typename type_traits<value_type>::real_type real_type;
+        real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
+        indexing_matrix_assign<scalar_assign> (cm, prod (e1, e2), column_major_tag ());
+        disable_type_check<bool>::value = true;
+#endif
+        size_type i_size = e1 ().size1 ();
+        size_type j_size = e2 ().size2 ();
+        size_type k_size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ());
+        for (size_type j_begin = 0; j_begin < j_size; j_begin += block_size) {
+            size_type j_end = j_begin + (std::min) (j_size - j_begin, block_size);
+            for (size_type i_begin = 0; i_begin < i_size; i_begin += block_size) {
+                size_type i_end = i_begin + (std::min) (i_size - i_begin, block_size);
+                // FIX: never ignore Martin Weiser's advice ;-(
+#ifdef BOOST_UBLAS_NO_CACHE
+                matrix_range<matrix_type> m_range (m, range (i_begin, i_end), range (j_begin, j_end));
+#else
+                // matrix<value_type, column_major, bounded_array<value_type, block_size * block_size> > m_range (i_end - i_begin, j_end - j_begin);
+                matrix<value_type, column_major> m_range (i_end - i_begin, j_end - j_begin);
+#endif
+                m_range.assign (zero_matrix<value_type> (i_end - i_begin, j_end - j_begin));
+                for (size_type k_begin = 0; k_begin < k_size; k_begin += block_size) {
+                    size_type k_end = k_begin + (std::min) (k_size - k_begin, block_size);
+#ifdef BOOST_UBLAS_NO_CACHE
+                    const matrix_range<expression1_type> e1_range (e1 (), range (i_begin, i_end), range (k_begin, k_end));
+                    const matrix_range<expression2_type> e2_range (e2 (), range (k_begin, k_end), range (j_begin, j_end));
+#else
+                    // const matrix<value_type, row_major, bounded_array<value_type, block_size * block_size> > e1_range (project (e1 (), range (i_begin, i_end), range (k_begin, k_end)));
+                    // const matrix<value_type, column_major, bounded_array<value_type, block_size * block_size> > e2_range (project (e2 (), range (k_begin, k_end), range (j_begin, j_end)));
+                    const matrix<value_type, row_major> e1_range (project (e1 (), range (i_begin, i_end), range (k_begin, k_end)));
+                    const matrix<value_type, column_major> e2_range (project (e2 (), range (k_begin, k_end), range (j_begin, j_end)));
+#endif
+                    m_range.plus_assign (prod (e1_range, e2_range));
+                }
+#ifndef BOOST_UBLAS_NO_CACHE
+                project (m, range (i_begin, i_end), range (j_begin, j_end)).assign (m_range);
+#endif
+            }
+        }
+#if BOOST_UBLAS_TYPE_CHECK
+        disable_type_check<bool>::value = false;
+        BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
+#endif
+        return m;
+    }
+
+    // Dispatcher
+    template<class M, typename M::size_type BS, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M
+    block_prod (const matrix_expression<E1> &e1,
+                const matrix_expression<E2> &e2) {
+        typedef typename M::orientation_category orientation_category;
+        return block_prod<M, BS> (e1, e2, orientation_category ());
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/operation_sparse.hpp b/include/boost/numeric/ublas/operation_sparse.hpp
new file mode 100644
index 0000000..b537d58
--- /dev/null
+++ b/include/boost/numeric/ublas/operation_sparse.hpp
@@ -0,0 +1,198 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_OPERATION_SPARSE_
+#define _BOOST_UBLAS_OPERATION_SPARSE_
+
+#include <boost/numeric/ublas/traits.hpp>
+
+// These scaled additions were borrowed from MTL unashamedly.
+// But Alexei Novakov had a lot of ideas to improve these. Thanks.
+
+namespace boost { namespace numeric { namespace ublas {
+
+    template<class M, class E1, class E2, class TRI>
+    BOOST_UBLAS_INLINE
+    M &
+    sparse_prod (const matrix_expression<E1> &e1,
+                 const matrix_expression<E2> &e2,
+                 M &m, TRI,
+                 row_major_tag) {
+        typedef M matrix_type;
+        typedef TRI triangular_restriction;
+        typedef const E1 expression1_type;
+        typedef const E2 expression2_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+
+        // ISSUE why is there a dense vector here?
+        vector<value_type> temporary (e2 ().size2 ());
+        temporary.clear ();
+        typename expression1_type::const_iterator1 it1 (e1 ().begin1 ());
+        typename expression1_type::const_iterator1 it1_end (e1 ().end1 ());
+        while (it1 != it1_end) {
+            size_type jb (temporary.size ());
+            size_type je (0);
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename expression1_type::const_iterator2 it2 (it1.begin ());
+            typename expression1_type::const_iterator2 it2_end (it1.end ());
+#else
+            typename expression1_type::const_iterator2 it2 (boost::numeric::ublas::begin (it1, iterator1_tag ()));
+            typename expression1_type::const_iterator2 it2_end (boost::numeric::ublas::end (it1, iterator1_tag ()));
+#endif
+            while (it2 != it2_end) {
+                // temporary.plus_assign (*it2 * row (e2 (), it2.index2 ()));
+                matrix_row<expression2_type> mr (e2 (), it2.index2 ());
+                typename matrix_row<expression2_type>::const_iterator itr (mr.begin ());
+                typename matrix_row<expression2_type>::const_iterator itr_end (mr.end ());
+                while (itr != itr_end) {
+                    size_type j (itr.index ());
+                    temporary (j) += *it2 * *itr;
+                    jb = (std::min) (jb, j);
+                    je = (std::max) (je, j);
+                    ++ itr;
+                }
+                ++ it2;
+            }
+            for (size_type j = jb; j < je + 1; ++ j) {
+                if (temporary (j) != value_type/*zero*/()) {
+                    // FIXME we'll need to extend the container interface!
+                    // m.push_back (it1.index1 (), j, temporary (j));
+                    // FIXME What to do with adaptors?
+                    // m.insert (it1.index1 (), j, temporary (j));
+                    if (triangular_restriction::other (it1.index1 (), j))
+                        m (it1.index1 (), j) = temporary (j);
+                    temporary (j) = value_type/*zero*/();
+                }
+            }
+            ++ it1;
+        }
+        return m;
+    }
+
+    template<class M, class E1, class E2, class TRI>
+    BOOST_UBLAS_INLINE
+    M &
+    sparse_prod (const matrix_expression<E1> &e1,
+                 const matrix_expression<E2> &e2,
+                 M &m, TRI,
+                 column_major_tag) {
+        typedef M matrix_type;
+        typedef TRI triangular_restriction;
+        typedef const E1 expression1_type;
+        typedef const E2 expression2_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::value_type value_type;
+
+        // ISSUE why is there a dense vector here?
+        vector<value_type> temporary (e1 ().size1 ());
+        temporary.clear ();
+        typename expression2_type::const_iterator2 it2 (e2 ().begin2 ());
+        typename expression2_type::const_iterator2 it2_end (e2 ().end2 ());
+        while (it2 != it2_end) {
+            size_type ib (temporary.size ());
+            size_type ie (0);
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            typename expression2_type::const_iterator1 it1 (it2.begin ());
+            typename expression2_type::const_iterator1 it1_end (it2.end ());
+#else
+            typename expression2_type::const_iterator1 it1 (boost::numeric::ublas::begin (it2, iterator2_tag ()));
+            typename expression2_type::const_iterator1 it1_end (boost::numeric::ublas::end (it2, iterator2_tag ()));
+#endif
+            while (it1 != it1_end) {
+                // column (m, it2.index2 ()).plus_assign (*it1 * column (e1 (), it1.index1 ()));
+                matrix_column<expression1_type> mc (e1 (), it1.index1 ());
+                typename matrix_column<expression1_type>::const_iterator itc (mc.begin ());
+                typename matrix_column<expression1_type>::const_iterator itc_end (mc.end ());
+                while (itc != itc_end) {
+                    size_type i (itc.index ());
+                    temporary (i) += *it1 * *itc;
+                    ib = (std::min) (ib, i);
+                    ie = (std::max) (ie, i);
+                    ++ itc;
+                }
+                ++ it1;
+            }
+            for (size_type i = ib; i < ie + 1; ++ i) {
+                if (temporary (i) != value_type/*zero*/()) {
+                    // FIXME we'll need to extend the container interface!
+                    // m.push_back (i, it2.index2 (), temporary (i));
+                    // FIXME What to do with adaptors?
+                    // m.insert (i, it2.index2 (), temporary (i));
+                    if (triangular_restriction::other (i, it2.index2 ()))
+                        m (i, it2.index2 ()) = temporary (i);
+                    temporary (i) = value_type/*zero*/();
+                }
+            }
+            ++ it2;
+        }
+        return m;
+    }
+
+    // Dispatcher
+    template<class M, class E1, class E2, class TRI>
+    BOOST_UBLAS_INLINE
+    M &
+    sparse_prod (const matrix_expression<E1> &e1,
+                 const matrix_expression<E2> &e2,
+                 M &m, TRI, bool init = true) {
+        typedef typename M::value_type value_type;
+        typedef TRI triangular_restriction;
+        typedef typename M::orientation_category orientation_category;
+
+        if (init)
+            m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
+        return sparse_prod (e1, e2, m, triangular_restriction (), orientation_category ());
+    }
+    template<class M, class E1, class E2, class TRI>
+    BOOST_UBLAS_INLINE
+    M
+    sparse_prod (const matrix_expression<E1> &e1,
+                 const matrix_expression<E2> &e2,
+                 TRI) {
+        typedef M matrix_type;
+        typedef TRI triangular_restriction;
+
+        matrix_type m (e1 ().size1 (), e2 ().size2 ());
+        // FIXME needed for c_matrix?!
+        // return sparse_prod (e1, e2, m, triangular_restriction (), false);
+        return sparse_prod (e1, e2, m, triangular_restriction (), true);
+    }
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M &
+    sparse_prod (const matrix_expression<E1> &e1,
+                 const matrix_expression<E2> &e2,
+                 M &m, bool init = true) {
+        typedef typename M::value_type value_type;
+        typedef typename M::orientation_category orientation_category;
+
+        if (init)
+            m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
+        return sparse_prod (e1, e2, m, full (), orientation_category ());
+    }
+    template<class M, class E1, class E2>
+    BOOST_UBLAS_INLINE
+    M
+    sparse_prod (const matrix_expression<E1> &e1,
+                 const matrix_expression<E2> &e2) {
+        typedef M matrix_type;
+
+        matrix_type m (e1 ().size1 (), e2 ().size2 ());
+        // FIXME needed for c_matrix?!
+        // return sparse_prod (e1, e2, m, full (), false);
+        return sparse_prod (e1, e2, m, full (), true);
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/operations.hpp b/include/boost/numeric/ublas/operations.hpp
new file mode 100644
index 0000000..23c4fab
--- /dev/null
+++ b/include/boost/numeric/ublas/operations.hpp
@@ -0,0 +1,26 @@
+/**
+ * -*- c++ -*-
+ *
+ * \file operations.hpp
+ *
+ * \brief This header includes several headers from the operation directory.
+ *
+ * Copyright (c) 2009, Gunter Winkler
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Gunter Winkler (guwi17 at gmx dot de)
+ */
+
+#ifndef BOOST_NUMERIC_UBLAS_OPERATIONS_HPP
+#define BOOST_NUMERIC_UBLAS_OPERATIONS_HPP
+
+#include <boost/numeric/ublas/operation/begin.hpp>
+#include <boost/numeric/ublas/operation/end.hpp>
+#include <boost/numeric/ublas/operation/num_columns.hpp>
+#include <boost/numeric/ublas/operation/num_rows.hpp>
+#include <boost/numeric/ublas/operation/size.hpp>
+
+#endif
diff --git a/include/boost/numeric/ublas/storage.hpp b/include/boost/numeric/ublas/storage.hpp
new file mode 100644
index 0000000..bd64892
--- /dev/null
+++ b/include/boost/numeric/ublas/storage.hpp
@@ -0,0 +1,2087 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef BOOST_UBLAS_STORAGE_H
+#define BOOST_UBLAS_STORAGE_H
+
+#include <algorithm>
+#ifdef BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR
+#include <boost/shared_array.hpp>
+#endif
+
+#include <boost/serialization/array.hpp>
+#include <boost/serialization/collection_size_type.hpp>
+#include <boost/serialization/nvp.hpp>
+
+#include <boost/numeric/ublas/exception.hpp>
+#include <boost/numeric/ublas/traits.hpp>
+#include <boost/numeric/ublas/detail/iterator.hpp>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+
+    // Base class for Storage Arrays - see the Barton Nackman trick
+    template<class E>
+    class storage_array:
+        private nonassignable {
+    };
+
+
+    // Unbounded array - with allocator
+    template<class T, class ALLOC>
+    class unbounded_array:
+        public storage_array<unbounded_array<T, ALLOC> > {
+
+        typedef unbounded_array<T, ALLOC> self_type;
+    public:
+        typedef ALLOC allocator_type;
+        typedef typename ALLOC::size_type size_type;
+        typedef typename ALLOC::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef const T *const_pointer;
+        typedef T *pointer;
+        typedef const_pointer const_iterator;
+        typedef pointer iterator;
+
+        // Construction and destruction
+        explicit BOOST_UBLAS_INLINE
+        unbounded_array (const ALLOC &a = ALLOC()):
+            alloc_ (a), size_ (0) {
+            data_ = 0;
+        }
+        explicit BOOST_UBLAS_INLINE
+        unbounded_array (size_type size, const ALLOC &a = ALLOC()):
+            alloc_(a), size_ (size) {
+          if (size_) {
+              data_ = alloc_.allocate (size_);
+              if (! detail::has_trivial_constructor<T>::value) {
+                  for (pointer d = data_; d != data_ + size_; ++d)
+                      alloc_.construct(d, value_type());
+              }
+          }
+          else
+              data_ = 0;
+        }
+        // No value initialised, but still be default constructed
+        BOOST_UBLAS_INLINE
+        unbounded_array (size_type size, const value_type &init, const ALLOC &a = ALLOC()):
+            alloc_ (a), size_ (size) {
+            if (size_) {
+                data_ = alloc_.allocate (size_);
+                std::uninitialized_fill (begin(), end(), init);
+            }
+            else
+                data_ = 0;
+        }
+        BOOST_UBLAS_INLINE
+        unbounded_array (const unbounded_array &c):
+            storage_array<unbounded_array<T, ALLOC> >(),
+            alloc_ (c.alloc_), size_ (c.size_) {
+            if (size_) {
+                data_ = alloc_.allocate (size_);
+                std::uninitialized_copy (c.begin(), c.end(), begin());
+            }
+            else
+                data_ = 0;
+        }
+        BOOST_UBLAS_INLINE
+        ~unbounded_array () {
+            if (size_) {
+                if (! detail::has_trivial_destructor<T>::value) {
+                    // std::_Destroy (begin(), end(), alloc_);
+                    const iterator i_end = end();
+                    for (iterator i = begin (); i != i_end; ++i) {
+                        iterator_destroy (i); 
+                    }
+                }
+                alloc_.deallocate (data_, size_);
+            }
+        }
+
+        // Resizing
+    private:
+        BOOST_UBLAS_INLINE
+        void resize_internal (const size_type size, const value_type init, const bool preserve) {
+            if (size != size_) {
+                pointer p_data = data_;
+                if (size) {
+                    data_ = alloc_.allocate (size);
+                    if (preserve) {
+                        pointer si = p_data;
+                        pointer di = data_;
+                        if (size < size_) {
+                            for (; di != data_ + size; ++di) {
+                                alloc_.construct (di, *si);
+                                ++si;
+                            }
+                        }
+                        else {
+                            for (; si != p_data + size_; ++si) {
+                                alloc_.construct (di, *si);
+                                ++di;
+                            }
+                            for (; di != data_ + size; ++di) {
+                                alloc_.construct (di, init);
+                            }
+                        }
+                    }
+                    else {
+                        if (! detail::has_trivial_constructor<T>::value) {
+                            for (pointer di = data_; di != data_ + size; ++di)
+                                alloc_.construct (di, value_type());
+                        }
+                    }
+                }
+
+                if (size_) {
+                    if (! detail::has_trivial_destructor<T>::value) {
+                        for (pointer si = p_data; si != p_data + size_; ++si)
+                            alloc_.destroy (si);
+                    }
+                    alloc_.deallocate (p_data, size_);
+                }
+
+                if (!size)
+                    data_ = 0;
+                size_ = size;
+            }
+        }
+    public:
+        BOOST_UBLAS_INLINE
+        void resize (size_type size) {
+            resize_internal (size, value_type (), false);
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, value_type init) {
+            resize_internal (size, init, true);
+        }
+                    
+        // Random Access Container
+        BOOST_UBLAS_INLINE
+        size_type max_size () const {
+            return ALLOC ().max_size();
+        }
+        
+        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];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return data_ [i];
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        unbounded_array &operator = (const unbounded_array &a) {
+            if (this != &a) {
+                resize (a.size_);
+                std::copy (a.data_, a.data_ + a.size_, data_);
+            }
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        unbounded_array &assign_temporary (unbounded_array &a) {
+            swap (a);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (unbounded_array &a) {
+            if (this != &a) {
+                std::swap (size_, a.size_);
+                std::swap (data_, a.data_);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (unbounded_array &a1, unbounded_array &a2) {
+            a1.swap (a2);
+        }
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return data_ + size_;
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return data_ + size_;
+        }
+
+        // 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 crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+        // Allocator
+        allocator_type get_allocator () {
+            return alloc_;
+        }
+
+    private:
+        friend class boost::serialization::access;
+
+        // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /*version*/)
+        { 
+            serialization::collection_size_type s(size_);
+            ar & serialization::make_nvp("size",s);
+            if ( Archive::is_loading::value ) {
+                resize(s);
+            }
+            ar & serialization::make_array(data_, s);
+        }
+
+    private:
+        // Handle explict destroy on a (possibly indexed) iterator
+        BOOST_UBLAS_INLINE
+        static void iterator_destroy (iterator &i) {
+            (&(*i)) -> ~value_type ();
+        }
+        ALLOC alloc_;
+        size_type size_;
+        pointer data_;
+    };
+
+    // Bounded array - with allocator for size_type and difference_type
+    template<class T, std::size_t N, class ALLOC>
+    class bounded_array:
+        public storage_array<bounded_array<T, N, ALLOC> > {
+
+        typedef bounded_array<T, N, ALLOC> self_type;
+    public:
+        // No allocator_type as ALLOC is not used for allocation
+        typedef typename ALLOC::size_type size_type;
+        typedef typename ALLOC::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef const T *const_pointer;
+        typedef T *pointer;
+        typedef const_pointer const_iterator;
+        typedef pointer iterator;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        bounded_array ():
+            size_ (0) /*, data_ ()*/ {   // size 0 - use bounded_vector to default construct with size N
+        }
+        explicit BOOST_UBLAS_INLINE
+        bounded_array (size_type size):
+            size_ (size) /*, data_ ()*/ {
+            BOOST_UBLAS_CHECK (size_ <= N, bad_size ());
+            // data_ (an array) elements are already default constructed
+        }
+        BOOST_UBLAS_INLINE
+        bounded_array (size_type size, const value_type &init):
+            size_ (size) /*, data_ ()*/ {
+            BOOST_UBLAS_CHECK (size_ <= N, bad_size ());
+            // ISSUE elements should be value constructed here, but we must fill instead as already default constructed
+            std::fill (begin(), end(), init) ;
+        }
+        BOOST_UBLAS_INLINE
+        bounded_array (const bounded_array &c):
+            size_ (c.size_)  {
+            // ISSUE elements should be copy constructed here, but we must copy instead as already default constructed
+            std::copy (c.begin(), c.end(), begin());
+        }
+        
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size) {
+            BOOST_UBLAS_CHECK (size <= N, bad_size ());
+            size_ = size;
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, value_type init) {
+            BOOST_UBLAS_CHECK (size <= N, bad_size ());
+            if (size > size_)
+                std::fill (data_ + size_, data_ + size, init);
+            size_ = size;
+        }
+
+        // Random Access Container
+        BOOST_UBLAS_INLINE
+        size_type max_size () const {
+            return N;
+        }
+        
+        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];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return data_ [i];
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        bounded_array &operator = (const bounded_array &a) {
+            if (this != &a) {
+                resize (a.size_);
+                std::copy (a.data_, a.data_ + a.size_, data_);
+            }
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        bounded_array &assign_temporary (bounded_array &a) { 
+            *this = a;
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (bounded_array &a) {
+            if (this != &a) {
+                std::swap (size_, a.size_);
+                std::swap_ranges (data_, data_ + (std::max) (size_, a.size_), a.data_);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (bounded_array &a1, bounded_array &a2) {
+            a1.swap (a2);
+        }
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return data_ + size_;
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return data_ + size_;
+        }
+
+        // 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 crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        // Serialization
+        friend class boost::serialization::access;
+
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /*version*/)
+        {
+            serialization::collection_size_type s(size_);
+            ar & serialization::make_nvp("size", s);
+            if ( Archive::is_loading::value ) {
+                if (s > N) bad_size("too large size in bounded_array::load()\n").raise();
+                resize(s);
+            }
+            ar & serialization::make_array(data_, s);
+        }
+
+    private:
+        size_type size_;
+// MSVC does not like arrays of size 0 in base classes.  Hence, this conditionally changes the size to 1
+#ifdef _MSC_VER
+        BOOST_UBLAS_BOUNDED_ARRAY_ALIGN value_type data_ [(N>0)?N:1];
+#else
+        BOOST_UBLAS_BOUNDED_ARRAY_ALIGN value_type data_ [N];
+#endif
+    };
+
+
+    // Array adaptor with normal deep copy semantics of elements
+    template<class T>
+    class array_adaptor:
+        public storage_array<array_adaptor<T> > {
+
+        typedef 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 T &reference;
+        typedef const T *const_pointer;
+        typedef T *pointer;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        array_adaptor ():
+            size_ (0), own_ (true), data_ (new value_type [0]) {
+        }
+        explicit BOOST_UBLAS_INLINE
+        array_adaptor (size_type size):
+            size_ (size), own_ (true), data_ (new value_type [size]) {
+        }
+        BOOST_UBLAS_INLINE
+        array_adaptor (size_type size, const value_type &init):
+            size_ (size), own_ (true), data_ (new value_type [size]) {
+            std::fill (data_, data_ + size_, init);
+        }
+        BOOST_UBLAS_INLINE
+        array_adaptor (size_type size, pointer data):
+            size_ (size), own_ (false), data_ (data) {}
+
+        template <size_t N>
+        BOOST_UBLAS_INLINE array_adaptor (T (&data)[N]):
+            size_ (N), own_ (false), data_ (data) {}
+        BOOST_UBLAS_INLINE
+        array_adaptor (const array_adaptor &a):
+            storage_array<self_type> (),
+            size_ (a.size_), own_ (true), data_ (new value_type [a.size_]) {
+            *this = a;
+        }
+        BOOST_UBLAS_INLINE
+        ~array_adaptor () {
+            if (own_) {
+                delete [] data_;
+            }
+        }
+
+        // Resizing
+    private:
+        BOOST_UBLAS_INLINE
+        void resize_internal (size_type size, value_type init, bool preserve = true) {
+           if (size != size_) {
+                pointer data = new value_type [size];
+                if (preserve) {
+                    std::copy (data_, data_ + (std::min) (size, size_), data);
+                    std::fill (data + (std::min) (size, size_), data + size, init);
+                }
+                if (own_)
+                    delete [] data_;
+                size_ = size;
+                own_ = true;
+                data_ = data;
+            }
+        }
+        BOOST_UBLAS_INLINE
+        void resize_internal (size_type size, pointer data, value_type init, bool preserve = true) {
+            if (data != data_) {
+                if (preserve) {
+                    std::copy (data_, data_ + (std::min) (size, size_), data);
+                    std::fill (data + (std::min) (size, size_), data + size, init);
+                }
+                if (own_)
+                    delete [] data_;
+                own_ = false;
+                data_ = data;
+            }
+            else {
+                std::fill (data + (std::min) (size, size_), data + size, init);
+            }
+            size_ = size;
+        }
+    public:
+        BOOST_UBLAS_INLINE
+        void resize (size_type size) {
+            resize_internal (size, value_type (), false);
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, value_type init) {
+            resize_internal (size, init, true);
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, pointer data) {
+            resize_internal (size, data, value_type (), false);
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, pointer data, value_type init) {
+            resize_internal (size, data, init, true);
+        }
+
+        template <size_t N>
+        BOOST_UBLAS_INLINE void resize (T (&data)[N]) {
+            resize_internal (N, data, value_type (), false);
+        }
+
+        template <size_t N>
+        BOOST_UBLAS_INLINE void resize (T (&data)[N], value_type init) {
+            resize_internal (N, data, init, true);
+        }
+
+        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];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return data_ [i];
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        array_adaptor &operator = (const array_adaptor &a) {
+            if (this != &a) {
+                resize (a.size_);
+                std::copy (a.data_, a.data_ + a.size_, data_);
+            }
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        array_adaptor &assign_temporary (array_adaptor &a) {
+            if (own_ && a.own_)
+                swap (a);
+            else
+                *this = a;
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (array_adaptor &a) {
+            if (this != &a) {
+                std::swap (size_, a.size_);
+                std::swap (own_, a.own_);
+                std::swap (data_, a.data_);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (array_adaptor &a1, array_adaptor &a2) {
+            a1.swap (a2);
+        }
+
+        // Iterators simply are pointers.
+
+        typedef const_pointer const_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return data_ + size_;
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        typedef pointer iterator;
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return data_ + size_;
+        }
+
+        // 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 crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        size_type size_;
+        bool own_;
+        pointer data_;
+    };
+
+#ifdef BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR
+    // Array adaptor with shallow (reference) copy semantics of elements.
+    // shared_array is used to maintain reference counts.
+    // This class breaks the normal copy semantics for a storage container and is very dangerous!
+    template<class T>
+    class shallow_array_adaptor:
+        public storage_array<shallow_array_adaptor<T> > {
+
+        typedef shallow_array_adaptor<T> self_type;
+
+        template<class TT>
+        struct leaker {
+            typedef void result_type;
+            typedef TT *argument_type;
+
+            BOOST_UBLAS_INLINE
+            result_type operator () (argument_type /* x */) {}
+        };
+
+    public:
+        typedef std::size_t size_type;
+        typedef std::ptrdiff_t difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef const T *const_pointer;
+        typedef T *pointer;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        shallow_array_adaptor ():
+            size_ (0), own_ (true), data_ (new value_type [0]) {
+        }
+        explicit BOOST_UBLAS_INLINE
+        shallow_array_adaptor (size_type size):
+            size_ (size), own_ (true), data_ (new value_type [size]) {
+        }
+        BOOST_UBLAS_INLINE
+        shallow_array_adaptor (size_type size, const value_type &init):
+            size_ (size), own_ (true), data_ (new value_type [size]) {
+            std::fill (data_.get (), data_.get () + size_, init);
+        }
+        BOOST_UBLAS_INLINE
+        shallow_array_adaptor (size_type size, pointer data):
+            size_ (size), own_ (false), data_ (data, leaker<value_type> ()) {}
+        template <size_t N>
+        BOOST_UBLAS_INLINE
+        shallow_array_adaptor (T (&data)[N]):
+            size_ (N), own_ (false), data_ (data, leaker<value_type> ()) {}
+
+        BOOST_UBLAS_INLINE
+        shallow_array_adaptor (const shallow_array_adaptor &a):
+            storage_array<self_type> (),
+            size_ (a.size_), own_ (a.own_), data_ (a.data_) {}
+
+        BOOST_UBLAS_INLINE
+        ~shallow_array_adaptor () {
+        }
+
+        // Resizing
+    private:
+        BOOST_UBLAS_INLINE
+        void resize_internal (size_type size, value_type init, bool preserve = true) {
+            if (size != size_) {
+                shared_array<value_type> data (new value_type [size]);
+                if (preserve) {
+                    std::copy (data_.get (), data_.get () + (std::min) (size, size_), data.get ());
+                    std::fill (data.get () + (std::min) (size, size_), data.get () + size, init);
+                }
+                size_ = size;
+                own_ = true;
+                data_ = data;
+            }
+        }
+        BOOST_UBLAS_INLINE
+        void resize_internal (size_type size, pointer data, value_type init, bool preserve = true) {
+            if (preserve) {
+                std::copy (data_.get (), data_.get () + (std::min) (size, size_), data);
+                std::fill (data + (std::min) (size, size_), data + size, init);
+            }
+            size_ = size;
+            own_ = false;
+            data_.reset(data, leaker<value_type> ());
+        }
+    public:
+        BOOST_UBLAS_INLINE
+        void resize (size_type size) {
+            resize_internal (size, value_type (), false);
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, value_type init) {
+            resize_internal (size, init, true);
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, pointer data) {
+            resize_internal (size, data, value_type (), false);
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, pointer data, value_type init) {
+            resize_internal (size, data, init, true);
+        }
+        template <size_t N>
+        BOOST_UBLAS_INLINE
+        void resize (T (&data)[N]) {
+            resize_internal (N, data, value_type (), false);
+        }
+        template <size_t N>
+        BOOST_UBLAS_INLINE
+        void resize (T (&data)[N], value_type init) {
+            resize_internal (N, data, init, true);
+        }
+
+        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];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return data_ [i];
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        shallow_array_adaptor &operator = (const shallow_array_adaptor &a) {
+            if (this != &a) {
+                resize (a.size_);
+                std::copy (a.data_.get (), a.data_.get () + a.size_, data_.get ());
+            }
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        shallow_array_adaptor &assign_temporary (shallow_array_adaptor &a) {
+            if (own_ && a.own_)
+                swap (a);
+            else
+                *this = a;
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (shallow_array_adaptor &a) {
+            if (this != &a) {
+                std::swap (size_, a.size_);
+                std::swap (own_, a.own_);
+                std::swap (data_, a.data_);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (shallow_array_adaptor &a1, shallow_array_adaptor &a2) {
+            a1.swap (a2);
+        }
+
+        // Iterators simply are pointers.
+
+        typedef const_pointer const_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return data_.get ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return data_.get () + size_;
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        typedef pointer iterator;
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return data_.get ();
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return data_.get () + size_;
+        }
+
+        // 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 crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        size_type size_;
+        bool own_;
+        shared_array<value_type> data_;
+    };
+
+#endif
+
+
+    // Range class
+    template <class Z, class D>
+    class basic_range {
+        typedef basic_range<Z, D> self_type;
+    public:
+        typedef Z size_type;
+        typedef D difference_type;
+        typedef size_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const value_type *const_pointer;
+        typedef value_type *pointer;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        basic_range ():
+            start_ (0), size_ (0) {}
+        BOOST_UBLAS_INLINE
+        basic_range (size_type start, size_type stop):
+            start_ (start), size_ (stop - start) {
+            BOOST_UBLAS_CHECK (start_ <= stop, bad_index ());
+        }
+
+        BOOST_UBLAS_INLINE
+        size_type start () const {
+            return start_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return size_;
+        }
+
+        // Random Access Container
+        BOOST_UBLAS_INLINE
+        size_type max_size () const {
+            return size_;
+        }
+        
+        BOOST_UBLAS_INLINE
+        bool empty () const {
+            return size_ == 0;
+        }
+            
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return start_ + i;
+        }
+
+        // Composition
+        BOOST_UBLAS_INLINE
+        basic_range compose (const basic_range &r) const {
+            return basic_range (start_ + r.start_, start_ + r.start_ + r.size_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const basic_range &r) const {
+            return start_ == r.start_ && size_ == r.size_;
+        }
+        BOOST_UBLAS_INLINE
+        bool operator != (const basic_range &r) const {
+            return ! (*this == r);
+        }
+
+        // Iterator types
+    private:
+        // Use and index
+        typedef size_type const_subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
+#else
+        class const_iterator:
+            public container_const_reference<basic_range>,
+            public random_access_iterator_base<std::random_access_iterator_tag,
+                                               const_iterator, value_type> {
+        public:
+            typedef typename basic_range::value_type value_type;
+            typedef typename basic_range::difference_type difference_type;
+            typedef typename basic_range::const_reference reference;
+            typedef typename basic_range::const_pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<basic_range> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const basic_range &r, const const_subiterator_type &it):
+                container_const_reference<basic_range> (r), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                BOOST_UBLAS_CHECK (n >= 0 || it_ >= size_type(-n), bad_index ());
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                BOOST_UBLAS_CHECK (n <= 0 || it_ >= size_type(n), bad_index ());
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK ((*this) ().start () <= it_, bad_index ());
+                BOOST_UBLAS_CHECK (it_ < (*this) ().start () + (*this) ().size (), bad_index ());
+                return it_;
+            }
+
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                BOOST_UBLAS_CHECK ((*this) ().start () <= it_, bad_index ());
+                BOOST_UBLAS_CHECK (it_ < (*this) ().start () + (*this) ().size (), bad_index ());
+                return it_ - (*this) ().start ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                // Comeau recommends...
+                this->assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return const_iterator (*this, start_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return const_iterator (*this, start_ + size_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // Reverse iterator
+        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+        BOOST_UBLAS_INLINE
+        basic_range preprocess (size_type size) const {
+            if (this != &all_)
+                return *this;
+            return basic_range (0, size);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        const basic_range &all () {
+            return all_;
+        }
+
+    private:
+        size_type start_;
+        size_type size_;
+        static const basic_range all_;
+    };
+
+    template <class Z, class D>
+    const basic_range<Z,D> basic_range<Z,D>::all_  (0, size_type (-1));
+
+
+    // Slice class
+    template <class Z, class D>
+    class basic_slice {
+        typedef basic_slice<Z, D> self_type;
+    public:
+        typedef Z size_type;
+        typedef D difference_type;
+        typedef size_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const value_type *const_pointer;
+        typedef value_type *pointer;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        basic_slice ():
+            start_ (0), stride_ (0), size_ (0) {}
+        BOOST_UBLAS_INLINE
+        basic_slice (size_type start, difference_type stride, size_type size):
+            start_ (start), stride_ (stride), size_ (size) {}
+
+        BOOST_UBLAS_INLINE
+        size_type start () const {
+            return start_;
+        }
+        BOOST_UBLAS_INLINE
+        difference_type stride () const {
+            return stride_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return size_;
+        }
+
+        // Random Access Container
+        BOOST_UBLAS_INLINE
+        size_type max_size () const {
+            return size_;
+        }
+        
+        BOOST_UBLAS_INLINE
+        bool empty () const {
+            return size_ == 0;
+        }
+            
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            BOOST_UBLAS_CHECK (stride_ >= 0 || start_ >= i * -stride_, bad_index ());
+            return start_ + i * stride_;
+        }
+
+        // Composition
+        BOOST_UBLAS_INLINE
+        basic_slice compose (const basic_range<size_type, difference_type> &r) const {
+            BOOST_UBLAS_CHECK (stride_ >=0 || start_ >= -stride_ * r.start(), bad_index ());
+            return basic_slice (start_ + stride_ * r.start (), stride_, r.size ());
+        }
+        BOOST_UBLAS_INLINE
+        basic_slice compose (const basic_slice &s) const {
+            BOOST_UBLAS_CHECK (stride_ >=0 || start_ >= -stride_ * s.start_, bad_index ());
+            return basic_slice (start_ + stride_ * s.start_, stride_ * s.stride_, s.size_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const basic_slice &s) const {
+            return start_ == s.start_ && stride_ == s.stride_ && size_ == s.size_; 
+        }
+        BOOST_UBLAS_INLINE
+        bool operator != (const basic_slice &s) const {
+            return ! (*this == s);
+        }
+
+        // Iterator types
+    private:
+        // Use and index
+        typedef size_type const_subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
+#else
+        class const_iterator:
+            public container_const_reference<basic_slice>,
+            public random_access_iterator_base<std::random_access_iterator_tag,
+                                               const_iterator, value_type> {
+        public:
+            typedef typename basic_slice::value_type value_type;
+            typedef typename basic_slice::difference_type difference_type;
+            typedef typename basic_slice::const_reference reference;
+            typedef typename basic_slice::const_pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<basic_slice> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const basic_slice &s, const const_subiterator_type &it):
+                container_const_reference<basic_slice> (s), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                BOOST_UBLAS_CHECK (it_ > 0, bad_index ());
+                --it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                BOOST_UBLAS_CHECK (n >= 0 || it_ >= size_type(-n), bad_index ());
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                BOOST_UBLAS_CHECK (n <= 0 || it_ >= size_type(n), bad_index ());
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
+                return (*this) ().start () + it_* (*this) ().stride ();
+            }
+
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
+                return it_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                // Comeau recommends...
+                this->assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return const_iterator (*this, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return const_iterator (*this, size_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // Reverse iterator
+        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+        BOOST_UBLAS_INLINE
+        basic_slice preprocess (size_type size) const {
+            if (this != &all_)
+                return *this;
+            return basic_slice (0, 1, size);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        const basic_slice &all () {
+            return all_;
+        }
+
+    private:
+        size_type start_;
+        difference_type stride_;
+        size_type size_;
+        static const basic_slice all_;
+    };
+
+    template <class Z, class D>
+    const basic_slice<Z,D> basic_slice<Z,D>::all_  (0, 1, size_type (-1));
+
+
+    // Indirect array class
+    template<class A>
+    class indirect_array {
+        typedef indirect_array<A> self_type;
+    public:
+        typedef A array_type;
+        typedef const A const_array_type;
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef typename A::value_type value_type;
+        typedef typename A::const_reference const_reference;
+        typedef typename A::reference reference;
+        typedef typename A::const_pointer const_pointer;
+        typedef typename A::pointer pointer;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        indirect_array ():
+            size_ (), data_ () {}
+        explicit BOOST_UBLAS_INLINE
+        indirect_array (size_type size):
+            size_ (size), data_ (size) {}
+        BOOST_UBLAS_INLINE
+        indirect_array (size_type size, const array_type &data):
+            size_ (size), data_ (data) {}
+        BOOST_UBLAS_INLINE
+        indirect_array (pointer start, pointer stop):
+            size_ (stop - start), data_ (stop - start) {
+            std::copy (start, stop, data_.begin ());
+        }
+
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return size_;
+        }
+        BOOST_UBLAS_INLINE
+        const_array_type data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        array_type data () {
+            return data_;
+        }
+
+        // Random Access Container
+        BOOST_UBLAS_INLINE
+        size_type max_size () const {
+            return size_;
+        }
+        
+        BOOST_UBLAS_INLINE
+        bool empty () const {
+            return data_.size () == 0;
+        }
+            
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return data_ [i];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return data_ [i];
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+
+        // Composition
+        BOOST_UBLAS_INLINE
+        indirect_array compose (const basic_range<size_type, difference_type> &r) const {
+            BOOST_UBLAS_CHECK (r.start () + r.size () <= size_, bad_size ());
+            array_type data (r.size ());
+            for (size_type i = 0; i < r.size (); ++ i)
+                data [i] = data_ [r.start () + i];
+            return indirect_array (r.size (), data);
+        }
+        BOOST_UBLAS_INLINE
+        indirect_array compose (const basic_slice<size_type, difference_type> &s) const {
+            BOOST_UBLAS_CHECK (s.start () + s.stride () * (s.size () - (s.size () > 0)) <= size (), bad_size ());
+            array_type data (s.size ());
+            for (size_type i = 0; i < s.size (); ++ i)
+                data [i] = data_ [s.start () + s.stride () * i];
+            return indirect_array (s.size (), data);
+        }
+        BOOST_UBLAS_INLINE
+        indirect_array compose (const indirect_array &ia) const {
+            array_type data (ia.size_);
+            for (size_type i = 0; i < ia.size_; ++ i) {
+                BOOST_UBLAS_CHECK (ia.data_ [i] <= size_, bad_size ());
+                data [i] = data_ [ia.data_ [i]];
+            }
+            return indirect_array (ia.size_, data);
+        }
+
+        // Comparison
+        template<class OA>
+        BOOST_UBLAS_INLINE
+        bool operator == (const indirect_array<OA> &ia) const {
+            if (size_ != ia.size_)
+                return false;
+            for (size_type i = 0; i < BOOST_UBLAS_SAME (size_, ia.size_); ++ i)
+                if (data_ [i] != ia.data_ [i])
+                    return false;
+            return true;
+        }
+        template<class OA>
+        BOOST_UBLAS_INLINE
+        bool operator != (const indirect_array<OA> &ia) const {
+            return ! (*this == ia);
+        }
+
+        // Iterator types
+    private:
+        // Use a index difference
+        typedef difference_type const_subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator<indirect_array, std::random_access_iterator_tag> const_iterator;
+#else
+        class const_iterator:
+            public container_const_reference<indirect_array>,
+            public random_access_iterator_base<std::random_access_iterator_tag,
+                                               const_iterator, value_type> {
+        public:
+            typedef typename indirect_array::value_type value_type;
+            typedef typename indirect_array::difference_type difference_type;
+            typedef typename indirect_array::const_reference reference;
+            typedef typename indirect_array::const_pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<indirect_array> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const indirect_array &ia, const const_subiterator_type &it):
+                container_const_reference<indirect_array> (ia), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return (*this) () (it_);
+            }
+
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                // Comeau recommends...
+                this->assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) () == it (), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return const_iterator (*this, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return const_iterator (*this, size_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // Reverse iterator
+        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+        BOOST_UBLAS_INLINE
+        indirect_array preprocess (size_type size) const {
+            if (this != &all_)
+                return *this;
+            indirect_array ia (size);
+            for (size_type i = 0; i < size; ++ i)
+               ia (i) = i;
+            return ia;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        const indirect_array &all () {
+            return all_;
+        }
+
+    private:
+        size_type size_;
+        array_type data_;
+        static const indirect_array all_;
+    };
+
+    template<class A>
+    const indirect_array<A> indirect_array<A>::all_;
+
+
+
+    // Gunter Winkler contributed the classes index_pair, index_pair_array,
+    // index_triple and index_triple_array to enable inplace sort of parallel arrays.
+
+    template <class V>
+    class index_pair :
+        public container_reference<V> {
+
+        typedef index_pair<V> self_type;
+    public:
+        typedef typename V::size_type size_type;
+
+        BOOST_UBLAS_INLINE
+        index_pair(V& v, size_type i) :
+            container_reference<V>(v), i_(i),
+            v1_(v.data1_[i]), v2_(v.data2_[i]),
+            dirty_(false), is_copy_(false) {}
+         BOOST_UBLAS_INLINE
+        index_pair(const self_type& rhs) :
+            container_reference<V>(rhs()), i_(0),
+            v1_(rhs.v1_), v2_(rhs.v2_),
+            dirty_(false), is_copy_(true) {}
+         BOOST_UBLAS_INLINE
+        ~index_pair() {
+            if (dirty_ && (!is_copy_) ) {
+                (*this)().data1_[i_] = v1_;
+                (*this)().data2_[i_] = v2_;
+            }
+        }
+
+        BOOST_UBLAS_INLINE
+        self_type& operator=(const self_type& rhs) {
+            v1_ = rhs.v1_;
+            v2_ = rhs.v2_;
+            dirty_ = true;
+            return *this;
+        }
+
+        BOOST_UBLAS_INLINE
+        void swap(self_type& rhs) {
+            self_type tmp(rhs);
+            rhs = *this;
+            *this = tmp;
+        }
+
+        BOOST_UBLAS_INLINE
+        friend void swap(self_type& lhs, self_type& rhs) {
+            lhs.swap(rhs);
+        }
+
+        friend void swap(self_type lhs, self_type rhs) { // For gcc 4.8 and c++11
+            lhs.swap(rhs);
+        }
+
+
+        BOOST_UBLAS_INLINE
+        bool equal(const self_type& rhs) const {
+            return (v1_ == rhs.v1_);
+        }
+        BOOST_UBLAS_INLINE
+        bool less(const self_type& rhs) const {
+            return (v1_ < rhs.v1_);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator == (const self_type& lhs, const self_type& rhs) {
+            return lhs.equal(rhs);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator != (const self_type& lhs, const self_type& rhs) {
+            return !lhs.equal(rhs);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator < (const self_type& lhs, const self_type& rhs) {
+            return lhs.less(rhs);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator >= (const self_type& lhs, const self_type& rhs) {
+            return !lhs.less(rhs);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator > (const self_type& lhs, const self_type& rhs) {
+            return rhs.less(lhs);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator <= (const self_type& lhs, const self_type& rhs) {
+            return !rhs.less(lhs);
+        }
+
+    private:
+        size_type i_;
+        typename V::value1_type v1_;
+        typename V::value2_type v2_;
+        bool dirty_;
+        bool is_copy_;
+     };
+
+    template <class V1, class V2>
+    class index_pair_array:
+        private boost::noncopyable {
+
+        typedef index_pair_array<V1, V2> self_type;
+    public:
+        typedef typename V1::value_type value1_type;
+        typedef typename V2::value_type value2_type;
+
+        typedef typename V1::size_type size_type;
+        typedef typename V1::difference_type difference_type;
+        typedef index_pair<self_type> value_type;
+        // There is nothing that can be referenced directly. Always return a copy of the index_pair
+        typedef value_type reference;
+        typedef const value_type const_reference;
+
+        BOOST_UBLAS_INLINE
+        index_pair_array(size_type size, V1& data1, V2& data2) :
+              size_(size),data1_(data1),data2_(data2) {}
+
+        BOOST_UBLAS_INLINE
+        size_type size() const {
+            return size_;
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return value_type((*this), i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            return value_type((*this), i);
+        }
+
+        typedef indexed_iterator<self_type, std::random_access_iterator_tag> iterator;
+        typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
+
+        BOOST_UBLAS_INLINE
+        iterator begin() {
+            return iterator( (*this), 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end() {
+            return iterator( (*this), size());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin() const {
+            return const_iterator( (*this), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end() const {
+            return const_iterator( (*this), size());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // unnecessary function:
+        BOOST_UBLAS_INLINE
+        bool equal(size_type i1, size_type i2) const {
+            return data1_[i1] == data1_[i2];
+        }
+        BOOST_UBLAS_INLINE
+        bool less(size_type i1, size_type i2) const {
+            return data1_[i1] < data1_[i2];
+        }
+
+        // gives a large speedup
+        BOOST_UBLAS_INLINE
+        friend void iter_swap(const iterator& lhs, const iterator& rhs) {
+            const size_type i1 = lhs.index();
+            const size_type i2 = rhs.index();
+            std::swap(lhs().data1_[i1], rhs().data1_[i2]);
+            std::swap(lhs().data2_[i1], rhs().data2_[i2]);
+        }
+
+    private:
+        size_type size_;
+        V1& data1_;
+        V2& data2_;
+
+        // friend class value_type;
+        friend class index_pair<self_type>;
+    };
+
+    template <class M>
+    class index_triple :
+        public container_reference<M> {
+
+        typedef index_triple<M> self_type;
+    public:
+        typedef typename M::size_type size_type;
+
+        BOOST_UBLAS_INLINE
+        index_triple(M& m, size_type i) :
+            container_reference<M>(m), i_(i),
+            v1_(m.data1_[i]), v2_(m.data2_[i]), v3_(m.data3_[i]),
+            dirty_(false), is_copy_(false) {}
+        BOOST_UBLAS_INLINE
+        index_triple(const self_type& rhs) :
+            container_reference<M>(rhs()), i_(0),
+            v1_(rhs.v1_), v2_(rhs.v2_), v3_(rhs.v3_),
+            dirty_(false), is_copy_(true) {}
+        BOOST_UBLAS_INLINE
+        ~index_triple() {
+            if (dirty_ && (!is_copy_) ) {
+                (*this)().data1_[i_] = v1_;
+                (*this)().data2_[i_] = v2_;
+                (*this)().data3_[i_] = v3_;
+            }
+        }
+
+        BOOST_UBLAS_INLINE
+        self_type& operator=(const self_type& rhs) {
+            v1_ = rhs.v1_;
+            v2_ = rhs.v2_;
+            v3_ = rhs.v3_;
+            dirty_ = true;
+            return *this;
+        }
+
+        BOOST_UBLAS_INLINE
+        void swap(self_type& rhs) {
+            self_type tmp(rhs);
+            rhs = *this;
+            *this = tmp;
+        }
+
+        BOOST_UBLAS_INLINE
+        friend void swap(self_type& lhs, self_type& rhs) {
+            lhs.swap(rhs);
+        }
+
+        friend void swap(self_type lhs, self_type rhs) { // For gcc 4.8 and c++11
+            lhs.swap(rhs);
+        }
+
+        BOOST_UBLAS_INLINE
+        bool equal(const self_type& rhs) const {
+            return ((v1_ == rhs.v1_) && (v2_ == rhs.v2_));
+        }
+        BOOST_UBLAS_INLINE
+        bool less(const self_type& rhs) const {
+            return ((v1_ < rhs.v1_) ||
+                    (v1_ == rhs.v1_ && v2_ < rhs.v2_));
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator == (const self_type& lhs, const self_type& rhs) {
+            return lhs.equal(rhs);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator != (const self_type& lhs, const self_type& rhs) {
+            return !lhs.equal(rhs);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator < (const self_type& lhs, const self_type& rhs) {
+            return lhs.less(rhs);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator >= (const self_type& lhs, const self_type& rhs) {
+            return !lhs.less(rhs);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator > (const self_type& lhs, const self_type& rhs) {
+            return rhs.less(lhs);
+        }
+        BOOST_UBLAS_INLINE
+        friend bool operator <= (const self_type& lhs, const self_type& rhs) {
+            return !rhs.less(lhs);
+        }
+
+    private:
+        size_type i_;
+        typename M::value1_type v1_;
+        typename M::value2_type v2_;
+        typename M::value3_type v3_;
+        bool dirty_;
+        bool is_copy_;
+    };
+
+    template <class V1, class V2, class V3>
+    class index_triple_array:
+        private boost::noncopyable {
+
+        typedef index_triple_array<V1, V2, V3> self_type;
+    public:
+        typedef typename V1::value_type value1_type;
+        typedef typename V2::value_type value2_type;
+        typedef typename V3::value_type value3_type;
+
+        typedef typename V1::size_type size_type;
+        typedef typename V1::difference_type difference_type;
+        typedef index_triple<self_type> value_type;
+        // There is nothing that can be referenced directly. Always return a copy of the index_triple
+        typedef value_type reference;
+        typedef const value_type const_reference;
+
+        BOOST_UBLAS_INLINE
+        index_triple_array(size_type size, V1& data1, V2& data2, V3& data3) :
+              size_(size),data1_(data1),data2_(data2),data3_(data3) {}
+
+        BOOST_UBLAS_INLINE
+        size_type size() const {
+            return size_;
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return value_type((*this), i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            return value_type((*this), i);
+        }
+
+        typedef indexed_iterator<self_type, std::random_access_iterator_tag> iterator;
+        typedef indexed_const_iterator<self_type, std::random_access_iterator_tag> const_iterator;
+
+        BOOST_UBLAS_INLINE
+        iterator begin() {
+            return iterator( (*this), 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end() {
+            return iterator( (*this), size());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin() const {
+            return const_iterator( (*this), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end() const {
+            return const_iterator( (*this), size());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // unnecessary function:
+        BOOST_UBLAS_INLINE
+        bool equal(size_type i1, size_type i2) const {
+            return ((data1_[i1] == data1_[i2]) && (data2_[i1] == data2_[i2]));
+        }
+        BOOST_UBLAS_INLINE
+        bool less(size_type i1, size_type i2) const {
+            return ((data1_[i1] < data1_[i2]) ||
+                    (data1_[i1] == data1_[i2] && data2_[i1] < data2_[i2]));
+        }
+
+        // gives a large speedup
+        BOOST_UBLAS_INLINE
+        friend void iter_swap(const iterator& lhs, const iterator& rhs) {
+            const size_type i1 = lhs.index();
+            const size_type i2 = rhs.index();
+            std::swap(lhs().data1_[i1], rhs().data1_[i2]);
+            std::swap(lhs().data2_[i1], rhs().data2_[i2]);
+            std::swap(lhs().data3_[i1], rhs().data3_[i2]);
+        }
+
+    private:
+        size_type size_;
+        V1& data1_;
+        V2& data2_;
+        V3& data3_;
+
+        // friend class value_type;
+        friend class index_triple<self_type>;
+    };
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/storage_sparse.hpp b/include/boost/numeric/ublas/storage_sparse.hpp
new file mode 100644
index 0000000..c8a64a9
--- /dev/null
+++ b/include/boost/numeric/ublas/storage_sparse.hpp
@@ -0,0 +1,579 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_STORAGE_SPARSE_
+#define _BOOST_UBLAS_STORAGE_SPARSE_
+
+#include <map>
+#include <boost/serialization/collection_size_type.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/array.hpp>
+#include <boost/serialization/map.hpp>
+#include <boost/serialization/base_object.hpp>
+
+#include <boost/numeric/ublas/storage.hpp>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    namespace detail {
+
+        template<class I, class T, class C>
+        BOOST_UBLAS_INLINE
+        I lower_bound (const I &begin, const I &end, const T &t, C compare) {
+            // t <= *begin <=> ! (*begin < t)
+            if (begin == end || ! compare (*begin, t))
+                return begin;
+            if (compare (*(end - 1), t))
+                return end;
+            return std::lower_bound (begin, end, t, compare);
+        }
+        template<class I, class T, class C>
+        BOOST_UBLAS_INLINE
+        I upper_bound (const I &begin, const I &end, const T &t, C compare) {
+            if (begin == end || compare (t, *begin))
+                return begin;
+            // (*end - 1) <= t <=> ! (t < *end)
+            if (! compare (t, *(end - 1)))
+                return end;
+            return std::upper_bound (begin, end, t, compare);
+        }
+
+        template<class P>
+        struct less_pair {
+            BOOST_UBLAS_INLINE
+            bool operator () (const P &p1, const P &p2) {
+                return p1.first < p2.first;
+            }
+        };
+        template<class T>
+        struct less_triple {
+            BOOST_UBLAS_INLINE
+            bool operator () (const T &t1, const T &t2) {
+                return t1.first.first < t2.first.first ||
+                       (t1.first.first == t2.first.first && t1.first.second < t2.first.second);
+            }
+        };
+
+    }
+
+#ifdef BOOST_UBLAS_STRICT_MAP_ARRAY
+    template<class A>
+    class sparse_storage_element:
+       public container_reference<A> {
+    public:
+        typedef A array_type;
+        typedef typename A::key_type index_type;
+        typedef typename A::mapped_type data_value_type;
+        // typedef const data_value_type &data_const_reference;
+        typedef typename type_traits<data_value_type>::const_reference data_const_reference;
+        typedef data_value_type &data_reference;
+        typedef typename A::value_type value_type;
+        typedef value_type *pointer;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        sparse_storage_element (array_type &a, pointer it):
+            container_reference<array_type> (a), it_ (it), i_ (it->first), d_ (it->second), dirty_ (false) {}
+        BOOST_UBLAS_INLINE
+        sparse_storage_element (array_type &a, index_type i):
+            container_reference<array_type> (a), it_ (), i_ (i), d_ (), dirty_ (false) {
+            pointer it = (*this) ().find (i_);
+            if (it == (*this) ().end ())
+                it = (*this) ().insert ((*this) ().end (), value_type (i_, d_));
+            d_ = it->second;
+        }
+        BOOST_UBLAS_INLINE
+        ~sparse_storage_element () {
+            if (dirty_) {
+                if (! it_)
+                    it_ = (*this) ().find (i_);
+                BOOST_UBLAS_CHECK (it_ != (*this) ().end (), internal_logic ());
+                it_->second = d_;
+            }
+        }
+
+        // Element access - only if data_const_reference is defined
+        BOOST_UBLAS_INLINE
+        typename data_value_type::data_const_reference
+        operator [] (index_type i) const {
+            return d_ [i];
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        sparse_storage_element &operator = (const sparse_storage_element &p) {
+            // Overide the implict copy assignment
+            d_ = p.d_;
+            dirty_ = true;
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_storage_element &operator = (const D &d) {
+            d_ = d;
+            dirty_ = true;
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_storage_element &operator += (const D &d) {
+            d_ += d;
+            dirty_ = true;
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_storage_element &operator -= (const D &d) {
+            d_ -= d;
+            dirty_ = true;
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_storage_element &operator *= (const D &d) {
+            d_ *= d;
+            dirty_ = true;
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_storage_element &operator /= (const D &d) {
+            d_ /= d;
+            dirty_ = true;
+            return *this;
+        }
+
+        // Comparison
+        template<class D>
+        BOOST_UBLAS_INLINE
+        bool operator == (const D &d) const {
+            return d_ == d;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        bool operator != (const D &d) const {
+            return d_ != d;
+        }
+
+        // Conversion
+        BOOST_UBLAS_INLINE
+        operator data_const_reference () const {
+            return d_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (sparse_storage_element p) {
+            if (this != &p) {
+                dirty_ = true;
+                p.dirty_ = true;
+                std::swap (d_, p.d_);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (sparse_storage_element p1, sparse_storage_element p2) {
+            p1.swap (p2);
+        }
+
+    private:
+        pointer it_;
+        index_type i_;
+        data_value_type d_;
+        bool dirty_;
+    };
+#endif
+
+
+    // Default map type is simply forwarded to std::map
+    // FIXME should use ALLOC for map but std::allocator of std::pair<const I, T> and std::pair<I,T> fail to compile
+    template<class I, class T, class ALLOC>
+    class map_std : public std::map<I, T /*, ALLOC */> {
+    public:
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+            ar & serialization::make_nvp("base", boost::serialization::base_object< std::map<I, T /*, ALLOC */> >(*this));
+        }
+    };
+
+    
+
+
+    // Map array
+    //  Implementation requires pair<I, T> allocator definition (without const)
+    template<class I, class T, class ALLOC>
+    class map_array {
+    public:
+        typedef ALLOC allocator_type;
+        typedef typename ALLOC::size_type size_type;
+        typedef typename ALLOC::difference_type difference_type;
+        typedef std::pair<I,T> value_type;
+        typedef I key_type;
+        typedef T mapped_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef const value_type *const_pointer;
+        typedef value_type *pointer;
+        // Iterators simply are pointers.
+        typedef const_pointer const_iterator;
+        typedef pointer iterator;
+
+        typedef const T &data_const_reference;
+#ifndef BOOST_UBLAS_STRICT_MAP_ARRAY
+        typedef T &data_reference;
+#else
+        typedef sparse_storage_element<map_array> data_reference;
+#endif
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        map_array (const ALLOC &a = ALLOC()):
+            alloc_(a), capacity_ (0), size_ (0) {
+                data_ = 0;
+        }
+        BOOST_UBLAS_INLINE
+        map_array (const map_array &c):
+            alloc_ (c.alloc_), capacity_ (c.size_), size_ (c.size_) {
+            if (capacity_) {
+                data_ = alloc_.allocate (capacity_);
+                std::uninitialized_copy (data_, data_ + capacity_, c.data_);
+                // capacity != size_ requires uninitialized_fill (size_ to capacity_)
+            }
+            else
+                data_ = 0;
+        }
+        BOOST_UBLAS_INLINE
+        ~map_array () {
+            if (capacity_) {
+                std::for_each (data_, data_ + capacity_, static_destroy);
+                alloc_.deallocate (data_, capacity_);
+            }
+        }
+
+    private:
+        // Resizing - implicitly exposses uninitialized (but default constructed) mapped_type
+        BOOST_UBLAS_INLINE
+        void resize (size_type size) {
+            BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ());
+            if (size > capacity_) {
+                const size_type capacity = size << 1;
+                BOOST_UBLAS_CHECK (capacity, internal_logic ());
+                pointer data = alloc_.allocate (capacity);
+                std::uninitialized_copy (data_, data_ + (std::min) (size, size_), data);
+                std::uninitialized_fill (data + (std::min) (size, size_), data + capacity, value_type ());
+
+                if (capacity_) {
+                    std::for_each (data_, data_ + capacity_, static_destroy);
+                    alloc_.deallocate (data_, capacity_);
+                }
+                capacity_ = capacity;
+                data_ = data;
+            }
+            size_ = size;
+            BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ());
+        }
+    public:
+
+        // Reserving
+        BOOST_UBLAS_INLINE
+        void reserve (size_type capacity) {
+            BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ());
+            // Reduce capacity_ if size_ allows
+            BOOST_UBLAS_CHECK (capacity >= size_, bad_size ());
+            pointer data;
+            if (capacity) {
+                data = alloc_.allocate (capacity);
+                std::uninitialized_copy (data_, data_ + size_, data);
+                std::uninitialized_fill (data + size_, data + capacity, value_type ());
+            }
+            else
+                data = 0;
+                
+            if (capacity_) {
+                std::for_each (data_, data_ + capacity_, static_destroy);
+                alloc_.deallocate (data_, capacity_);
+            }
+            capacity_ = capacity;
+            data_ = data;
+            BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ());
+        }
+
+        // Random Access Container
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return size_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type capacity () const {
+            return capacity_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type max_size () const {
+            return 0; //TODO
+        }
+       
+        BOOST_UBLAS_INLINE
+        bool empty () const {
+            return size_ == 0;
+        }
+            
+        // Element access
+        BOOST_UBLAS_INLINE
+        data_reference operator [] (key_type i) {
+#ifndef BOOST_UBLAS_STRICT_MAP_ARRAY
+            pointer it = find (i);
+            if (it == end ())
+                it = insert (end (), value_type (i, mapped_type (0)));
+            BOOST_UBLAS_CHECK (it != end (), internal_logic ());
+            return it->second;
+#else
+            return data_reference (*this, i);
+#endif
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        map_array &operator = (const map_array &a) {
+            if (this != &a) {
+                resize (a.size_);
+                std::copy (a.data_, a.data_ + a.size_, data_);
+            }
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        map_array &assign_temporary (map_array &a) {
+            swap (a);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (map_array &a) {
+            if (this != &a) {
+                std::swap (capacity_, a.capacity_);
+                std::swap (data_, a.data_);
+                std::swap (size_, a.size_);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (map_array &a1, map_array &a2) {
+            a1.swap (a2);
+        }
+
+        // Element insertion and deletion
+        
+        // From Back Insertion Sequence concept
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator push_back (iterator it, const value_type &p) {
+            if (size () == 0 || (it = end () - 1)->first < p.first) {
+                resize (size () + 1);
+                *(it = end () - 1) = p;
+                return it;
+            }
+            external_logic ().raise ();
+            return it;
+        }
+        // Form Unique Associative Container concept
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        std::pair<iterator,bool> insert (const value_type &p) {
+            iterator it = detail::lower_bound (begin (), end (), p, detail::less_pair<value_type> ());
+            if (it != end () && it->first == p.first)
+                return std::make_pair (it, false);
+            difference_type n = it - begin ();
+            resize (size () + 1);
+            it = begin () + n;    // allow for invalidation
+            std::copy_backward (it, end () - 1, end ());
+            *it = p;
+            return std::make_pair (it, true);
+        }
+        // Form Sorted Associative Container concept
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator insert (iterator hint, const value_type &p) {
+            return insert (p).first;
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        void erase (iterator it) {
+            BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ());
+            std::copy (it + 1, end (), it);
+            resize (size () - 1);
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        void erase (iterator it1, iterator it2) {
+            if (it1 == it2) return /* nothing to erase */;
+            BOOST_UBLAS_CHECK (begin () <= it1 && it1 < it2 && it2 <= end (), bad_index ());
+            std::copy (it2, end (), it1);
+            resize (size () - (it2 - it1));
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        void clear () {
+            resize (0);
+        }
+
+        // Element lookup
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator find (key_type i) const {
+            const_iterator it (detail::lower_bound (begin (), end (), value_type (i, mapped_type (0)), detail::less_pair<value_type> ()));
+            if (it == end () || it->first != i)
+                it = end ();
+            return it;
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator find (key_type i) {
+            iterator it (detail::lower_bound (begin (), end (), value_type (i, mapped_type (0)), detail::less_pair<value_type> ()));
+            if (it == end () || it->first != i)
+                it = end ();
+            return it;
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator lower_bound (key_type i) const {
+            return detail::lower_bound (begin (), end (), value_type (i, mapped_type (0)), detail::less_pair<value_type> ());
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator lower_bound (key_type i) {
+            return detail::lower_bound (begin (), end (), value_type (i, mapped_type (0)), detail::less_pair<value_type> ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return data_ + size_;
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return data_ + size_;
+        }
+
+        // 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 crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+        // Allocator
+        allocator_type get_allocator () {
+            return alloc_;
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+            serialization::collection_size_type s (size_);
+            ar & serialization::make_nvp("size",s);
+            if (Archive::is_loading::value) {
+                resize(s);
+            }
+            ar & serialization::make_array(data_, s);
+        }
+
+    private:
+        // Provide destroy as a non member function
+        BOOST_UBLAS_INLINE
+        static void static_destroy (reference p) {
+            (&p) -> ~value_type ();
+        }
+        ALLOC alloc_;
+        size_type capacity_;
+        pointer data_;
+        size_type size_;
+    };
+
+
+    namespace detail {
+        template<class A, class T>
+        struct map_traits {
+            typedef typename A::mapped_type &reference;
+        };
+        template<class I, class T, class ALLOC>
+        struct map_traits<map_array<I, T, ALLOC>, T > {
+            typedef typename map_array<I, T, ALLOC>::data_reference reference;
+        };
+
+        // reserve helpers for map_array and generic maps
+        // ISSUE should be in map_traits but want to use on all compilers
+
+        template<class M>
+        BOOST_UBLAS_INLINE
+        void map_reserve (M &/* m */, typename M::size_type /* capacity */) {
+        }
+        template<class I, class T, class ALLOC>
+        BOOST_UBLAS_INLINE
+        void map_reserve (map_array<I, T, ALLOC> &m, typename map_array<I, T, ALLOC>::size_type capacity) {
+            m.reserve (capacity);
+        }
+
+        template<class M>
+        struct map_capacity_traits {
+            typedef typename M::size_type type ;
+            type operator() ( M const& m ) const {
+               return m.size ();
+            }
+        } ;
+
+        template<class I, class T, class ALLOC>
+        struct map_capacity_traits< map_array<I, T, ALLOC> > {
+            typedef typename map_array<I, T, ALLOC>::size_type type ;
+            type operator() ( map_array<I, T, ALLOC> const& m ) const {
+               return m.capacity ();
+            }
+        } ;
+
+        template<class M>
+        BOOST_UBLAS_INLINE
+        typename map_capacity_traits<M>::type map_capacity (M const& m) {
+            return map_capacity_traits<M>() ( m );
+        }
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/symmetric.hpp b/include/boost/numeric/ublas/symmetric.hpp
new file mode 100644
index 0000000..9a40969
--- /dev/null
+++ b/include/boost/numeric/ublas/symmetric.hpp
@@ -0,0 +1,2309 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_SYMMETRIC_
+#define _BOOST_UBLAS_SYMMETRIC_
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/detail/temporary.hpp>
+
+// Iterators based on ideas of Jeremy Siek
+// Symmetric matrices are square. Thanks to Peter Schmitteckert for spotting this.
+
+namespace boost { namespace numeric { namespace ublas {
+
+    template<class M>
+    bool is_symmetric (const M &m) {
+        typedef typename M::size_type size_type;
+
+        if (m.size1 () != m.size2 ())
+            return false;
+        size_type size = BOOST_UBLAS_SAME (m.size1 (), m.size2 ());
+        for (size_type i = 0; i < size; ++ i) {
+            for (size_type j = i; j < size; ++ j) {
+                if (m (i, j) != m (j, i))
+                    return false;
+            }
+        }
+        return true;
+    }
+
+    // Array based symmetric matrix class
+    template<class T, class TRI, class L, class A>
+    class symmetric_matrix:
+        public matrix_container<symmetric_matrix<T, TRI, L, A> > {
+
+        typedef T *pointer;
+        typedef TRI triangular_type;
+        typedef L layout_type;
+        typedef symmetric_matrix<T, TRI, L, A> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef A array_type;
+
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef vector<T, A> vector_temporary_type;
+        typedef matrix<T, L, A> matrix_temporary_type;  // general sub-matrix
+        typedef packed_tag storage_category;
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        symmetric_matrix ():
+            matrix_container<self_type> (),
+            size_ (0), data_ (0) {}
+        BOOST_UBLAS_INLINE
+        symmetric_matrix (size_type size):
+            matrix_container<self_type> (),
+            size_ (BOOST_UBLAS_SAME (size, size)), data_ (triangular_type::packed_size (layout_type (), size, size)) {
+        }
+        BOOST_UBLAS_INLINE
+        symmetric_matrix (size_type size1, size_type size2):
+            matrix_container<self_type> (),
+            size_ (BOOST_UBLAS_SAME (size1, size2)), data_ (triangular_type::packed_size (layout_type (), size1, size2)) {
+        }
+        BOOST_UBLAS_INLINE
+        symmetric_matrix (size_type size, const array_type &data):
+            matrix_container<self_type> (),
+            size_ (size), data_ (data) {}
+        BOOST_UBLAS_INLINE
+        symmetric_matrix (const symmetric_matrix &m):
+            matrix_container<self_type> (),
+            size_ (m.size_), data_ (m.data_) {}
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_matrix (const matrix_expression<AE> &ae):
+            matrix_container<self_type> (),
+            size_ (BOOST_UBLAS_SAME (ae ().size1 (), ae ().size2 ())),
+            data_ (triangular_type::packed_size (layout_type (), size_, size_)) {
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const array_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, bool preserve = true) {
+            if (preserve) {
+                self_type temporary (size, size);
+                detail::matrix_resize_preserve<layout_type, triangular_type> (*this, temporary);
+            }
+            else {
+                data ().resize (triangular_type::packed_size (layout_type (), size, size));
+                size_ = size;
+            }
+        }
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            resize (BOOST_UBLAS_SAME (size1, size2), preserve);
+        }
+        BOOST_UBLAS_INLINE
+        void resize_packed_preserve (size_type size) {
+            size_ = BOOST_UBLAS_SAME (size, size);
+            data ().resize (triangular_type::packed_size (layout_type (), size_, size_), value_type ());
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_, bad_index ());
+            if (triangular_type::other (i, j))
+                return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
+            else
+                return data () [triangular_type::element (layout_type (), j, size_, i, size_)];
+        }
+        BOOST_UBLAS_INLINE
+        reference at_element (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_, bad_index ());
+            return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size_, bad_index ());
+            if (triangular_type::other (i, j))
+                return data () [triangular_type::element (layout_type (), i, size_, j, size_)];
+            else
+                return data () [triangular_type::element (layout_type (), j, size_, i, size_)];
+        }
+
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        reference insert_element (size_type i, size_type j, const_reference t) {
+            return (operator () (i, j) = t);
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i, size_type j) {
+            operator () (i, j) = value_type/*zero*/();
+        }
+        
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            // data ().clear ();
+            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        symmetric_matrix &operator = (const symmetric_matrix &m) {
+            size_ = m.size_;
+            data () = m.data ();
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        symmetric_matrix &assign_temporary (symmetric_matrix &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_matrix &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_matrix &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_matrix& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_matrix &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_matrix& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_matrix &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        symmetric_matrix& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        symmetric_matrix& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (symmetric_matrix &m) {
+            if (this != &m) {
+                std::swap (size_, m.size_);
+                data ().swap (m.data ());
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (symmetric_matrix &m1, symmetric_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int /* rank */, size_type i, size_type j) const {
+            return const_iterator1 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
+            if (rank == 0)
+                i = triangular_type::global_mutable_restrict1 (i, size1(), j, size2());
+            return iterator1 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int /* rank */, size_type i, size_type j) const {
+            return const_iterator2 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
+            if (rank == 0)
+                j = triangular_type::global_mutable_restrict2 (i, size1(), j, size2());
+            return iterator2 (*this, i, j);
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<symmetric_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename symmetric_matrix::value_type value_type;
+            typedef typename symmetric_matrix::difference_type difference_type;
+            typedef typename symmetric_matrix::const_reference reference;
+            typedef const typename symmetric_matrix::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, size_type it1, size_type it2):
+                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, it1_, 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<symmetric_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename symmetric_matrix::value_type value_type;
+            typedef typename symmetric_matrix::difference_type difference_type;
+            typedef typename symmetric_matrix::reference reference;
+            typedef typename symmetric_matrix::pointer pointer;
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, size_type it1, size_type it2):
+                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                return (*this) ().find2 (1, it1_, 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size_, 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<symmetric_matrix>,
+            public random_access_iterator_base<dense_random_access_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename symmetric_matrix::value_type value_type;
+            typedef typename symmetric_matrix::difference_type difference_type;
+            typedef typename symmetric_matrix::const_reference reference;
+            typedef const typename symmetric_matrix::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, size_type it1, size_type it2):
+                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<symmetric_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename symmetric_matrix::value_type value_type;
+            typedef typename symmetric_matrix::difference_type difference_type;
+            typedef typename symmetric_matrix::reference reference;
+            typedef typename symmetric_matrix::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, size_type it1, size_type it2):
+                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                return (*this) ().find1 (1, 0, it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        size_type size_;
+        array_type data_;
+    };
+
+
+    // Symmetric matrix adaptor class
+    template<class M, class TRI>
+    class symmetric_adaptor:
+        public matrix_expression<symmetric_adaptor<M, TRI> > {
+
+        typedef symmetric_adaptor<M, TRI> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef const M const_matrix_type;
+        typedef M matrix_type;
+        typedef TRI triangular_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        // Replaced by _temporary_traits to avoid type requirements on M
+        //typedef typename M::vector_temporary_type vector_temporary_type;
+        //typedef typename M::matrix_temporary_type matrix_temporary_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 packed_proxy_tag>::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor (matrix_type &data):
+            matrix_expression<self_type> (),
+            data_ (data) {
+            BOOST_UBLAS_CHECK (data_.size1 () == data_.size2 (), bad_size ());
+        }
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor (const symmetric_adaptor &m):
+            matrix_expression<self_type> (),
+            data_ (m.data_) {
+            BOOST_UBLAS_CHECK (data_.size1 () == data_.size2 (), bad_size ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return data_.size1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return data_.size2 ();
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+            if (triangular_type::other (i, j))
+                return data () (i, j);
+            else
+                return data () (j, i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+            if (triangular_type::other (i, j))
+                return data () (i, j);
+            else
+                return data () (j, i);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+            if (triangular_type::other (i, j))
+                return data () (i, j);
+            else
+                return data () (j, i);
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor &operator = (const symmetric_adaptor &m) {
+            matrix_assign<scalar_assign, triangular_type> (*this, m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor &assign_temporary (symmetric_adaptor &m) {
+            *this = m;
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor &operator = (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign, triangular_type> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor& operator += (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign, triangular_type> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor& operator -= (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign, triangular_type> (*this, matrix<value_type> (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign, triangular_type> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        symmetric_adaptor& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const symmetric_adaptor &sa) const {
+            return (*this).data ().same_closure (sa.data ());
+       }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (symmetric_adaptor &m) {
+            if (this != &m)
+                matrix_swap<scalar_swap, triangular_type> (*this, m);
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (symmetric_adaptor &m1, symmetric_adaptor &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+    private:
+        // Use matrix iterator
+        typedef typename M::const_iterator1 const_subiterator1_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator1,
+                                          typename M::iterator1>::type subiterator1_type;
+        typedef typename M::const_iterator2 const_subiterator2_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator2,
+                                          typename M::iterator2>::type subiterator2_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            if (triangular_type::other (i, j)) {
+                if (triangular_type::other (size1 (), j)) {
+                    return const_iterator1 (*this, 0, 0,
+                                            data ().find1 (rank, i, j), data ().find1 (rank, size1 (), j),
+                                            data ().find2 (rank, size2 (), size1 ()), data ().find2 (rank, size2 (), size1 ()));
+                } else {
+                    return const_iterator1 (*this, 0, 1,
+                                            data ().find1 (rank, i, j), data ().find1 (rank, j, j),
+                                            data ().find2 (rank, j, j), data ().find2 (rank, j, size1 ()));
+                }
+            } else {
+                if (triangular_type::other (size1 (), j)) {
+                    return const_iterator1 (*this, 1, 0,
+                                            data ().find1 (rank, j, j), data ().find1 (rank, size1 (), j),
+                                            data ().find2 (rank, j, i), data ().find2 (rank, j, j));
+                } else {
+                    return const_iterator1 (*this, 1, 1,
+                                            data ().find1 (rank, size1 (), size2 ()), data ().find1 (rank, size1 (), size2 ()),
+                                            data ().find2 (rank, j, i), data ().find2 (rank, j, size1 ()));
+                }
+            }
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
+            return iterator1 (*this, data ().find1 (rank, i, j));
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            if (triangular_type::other (i, j)) {
+                if (triangular_type::other (i, size2 ())) {
+                    return const_iterator2 (*this, 1, 1,
+                                            data ().find1 (rank, size2 (), size1 ()), data ().find1 (rank, size2 (), size1 ()),
+                                            data ().find2 (rank, i, j), data ().find2 (rank, i, size2 ()));
+                } else {
+                    return const_iterator2 (*this, 1, 0,
+                                            data ().find1 (rank, i, i), data ().find1 (rank, size2 (), i),
+                                            data ().find2 (rank, i, j), data ().find2 (rank, i, i));
+                }
+            } else {
+                if (triangular_type::other (i, size2 ())) {
+                    return const_iterator2 (*this, 0, 1,
+                                            data ().find1 (rank, j, i), data ().find1 (rank, i, i),
+                                            data ().find2 (rank, i, i), data ().find2 (rank, i, size2 ()));
+                } else {
+                    return const_iterator2 (*this, 0, 0,
+                                            data ().find1 (rank, j, i), data ().find1 (rank, size2 (), i),
+                                            data ().find2 (rank, size1 (), size2 ()), data ().find2 (rank, size2 (), size2 ()));
+                }
+            }
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
+            return iterator2 (*this, data ().find2 (rank, i, j));
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<symmetric_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename const_subiterator1_type::iterator_category, dense_random_access_iterator_tag>::iterator_category,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename const_subiterator1_type::value_type value_type;
+            typedef typename const_subiterator1_type::difference_type difference_type;
+            typedef typename const_subiterator1_type::reference reference;
+            typedef typename const_subiterator1_type::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (),
+                begin_ (-1), end_ (-1), current_ (-1),
+                it1_begin_ (), it1_end_ (), it1_ (),
+                it2_begin_ (), it2_end_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, int begin, int end,
+                             const const_subiterator1_type &it1_begin, const const_subiterator1_type &it1_end,
+                             const const_subiterator2_type &it2_begin, const const_subiterator2_type &it2_end):
+                container_const_reference<self_type> (m),
+                begin_ (begin), end_ (end), current_ (begin),
+                it1_begin_ (it1_begin), it1_end_ (it1_end), it1_ (it1_begin_),
+                it2_begin_ (it2_begin), it2_end_ (it2_end), it2_ (it2_begin_) {
+                if (current_ == 0 && it1_ == it1_end_)
+                    current_ = 1;
+                if (current_ == 1 && it2_ == it2_end_)
+                    current_ = 0;
+                if ((current_ == 0 && it1_ == it1_end_) ||
+                    (current_ == 1 && it2_ == it2_end_))
+                    current_ = end_;
+                BOOST_UBLAS_CHECK (current_ == end_ ||
+                                   (current_ == 0 && it1_ != it1_end_) ||
+                                   (current_ == 1 && it2_ != it2_end_), internal_logic ());
+            }
+            // FIXME cannot compile
+            //  iterator1 does not have these members!
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()),
+                begin_ (it.begin_), end_ (it.end_), current_ (it.current_),
+                it1_begin_ (it.it1_begin_), it1_end_ (it.it1_end_), it1_ (it.it1_),
+                it2_begin_ (it.it2_begin_), it2_end_ (it.it2_end_), it2_ (it.it2_) {
+                BOOST_UBLAS_CHECK (current_ == end_ ||
+                                   (current_ == 0 && it1_ != it1_end_) ||
+                                   (current_ == 1 && it2_ != it2_end_), internal_logic ());
+            }
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    ++ it1_;
+                    if (it1_ == it1_end_ && end_ == 1) {
+                        it2_ = it2_begin_;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    ++ it2_;
+                    if (it2_ == it2_end_ && end_ == 0) {
+                        it1_ = it1_begin_;
+                        current_ = 0;
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    if (it1_ == it1_begin_ && begin_ == 1) {
+                        it2_ = it2_end_;
+                        BOOST_UBLAS_CHECK (it2_ != it2_begin_, internal_logic ());
+                        -- it2_;
+                        current_ = 1;
+                    } else {
+                        -- it1_;
+                    }
+                } else /* if (current_ == 1) */ {
+                    if (it2_ == it2_begin_ && begin_ == 0) {
+                        it1_ = it1_end_;
+                        BOOST_UBLAS_CHECK (it1_ != it1_begin_, internal_logic ());
+                        -- it1_;
+                        current_ = 0;
+                    } else {
+                        -- it2_;
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    size_type d = (std::min) (n, it1_end_ - it1_);
+                    it1_ += d;
+                    n -= d;
+                    if (n > 0 || (end_ == 1 && it1_ == it1_end_)) {
+                        BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
+                        d = (std::min) (n, it2_end_ - it2_begin_);
+                        it2_ = it2_begin_ + d;
+                        n -= d;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    size_type d = (std::min) (n, it2_end_ - it2_);
+                    it2_ += d;
+                    n -= d;
+                    if (n > 0 || (end_ == 0 && it2_ == it2_end_)) {
+                        BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
+                        d = (std::min) (n, it1_end_ - it1_begin_);
+                        it1_ = it1_begin_ + d;
+                        n -= d;
+                        current_ = 0;
+                    }
+                }
+                BOOST_UBLAS_CHECK (n == 0, external_logic ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    size_type d = (std::min) (n, it1_ - it1_begin_);
+                    it1_ -= d;
+                    n -= d;
+                    if (n > 0) {
+                        BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
+                        d = (std::min) (n, it2_end_ - it2_begin_);
+                        it2_ = it2_end_ - d;
+                        n -= d;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    size_type d = (std::min) (n, it2_ - it2_begin_);
+                    it2_ -= d;
+                    n -= d;
+                    if (n > 0) {
+                        BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
+                        d = (std::min) (n, it1_end_ - it1_begin_);
+                        it1_ = it1_end_ - d;
+                        n -= d;
+                        current_ = 0;
+                    }
+                }
+                BOOST_UBLAS_CHECK (n == 0, external_logic ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
+                if (current_ == 0 && it.current_ == 0) {
+                    return it1_ - it.it1_;
+                } else if (current_ == 0 && it.current_ == 1) {
+                    if (end_ == 1 && it.end_ == 1) {
+                        return (it1_ - it.it1_end_) + (it.it2_begin_ - it.it2_);
+                    } else /* if (end_ == 0 && it.end_ == 0) */ {
+                        return (it1_ - it.it1_begin_) + (it.it2_end_ - it.it2_);
+                    }
+
+                } else if (current_ == 1 && it.current_ == 0) {
+                    if (end_ == 1 && it.end_ == 1) {
+                        return (it2_ - it.it2_begin_) + (it.it1_end_ - it.it1_);
+                    } else /* if (end_ == 0 && it.end_ == 0) */ {
+                        return (it2_ - it.it2_end_) + (it.it1_begin_ - it.it1_);
+                    }
+                }
+                /* current_ == 1 && it.current_ == 1 */ {
+                    return it2_ - it.it2_;
+                }
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    return *it1_;
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    return *it2_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    return it1_.index1 ();
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    return it2_.index2 ();
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    return it1_.index2 ();
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    return it2_.index1 ();
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                begin_ = it.begin_;
+                end_ = it.end_;
+                current_ = it.current_;
+                it1_begin_ = it.it1_begin_;
+                it1_end_ = it.it1_end_;
+                it1_ = it.it1_;
+                it2_begin_ = it.it2_begin_;
+                it2_end_ = it.it2_end_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
+                return (current_ == 0 && it.current_ == 0 && it1_ == it.it1_) ||
+                       (current_ == 1 && it.current_ == 1 && it2_ == it.it2_);
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it - *this > 0;
+            }
+
+        private:
+            int begin_;
+            int end_;
+            int current_;
+            const_subiterator1_type it1_begin_;
+            const_subiterator1_type it1_end_;
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_begin_;
+            const_subiterator2_type it2_end_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<symmetric_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               iterator1, value_type> {
+        public:
+            typedef typename subiterator1_type::value_type value_type;
+            typedef typename subiterator1_type::difference_type difference_type;
+            typedef typename subiterator1_type::reference reference;
+            typedef typename subiterator1_type::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it1_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, const subiterator1_type &it1):
+                container_reference<self_type> (m), it1_ (it1) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return *it1_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it1_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            subiterator1_type it1_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1 (), 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<symmetric_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename const_subiterator2_type::iterator_category, dense_random_access_iterator_tag>::iterator_category,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename const_subiterator2_type::value_type value_type;
+            typedef typename const_subiterator2_type::difference_type difference_type;
+            typedef typename const_subiterator2_type::reference reference;
+            typedef typename const_subiterator2_type::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (),
+                begin_ (-1), end_ (-1), current_ (-1),
+                it1_begin_ (), it1_end_ (), it1_ (),
+                it2_begin_ (), it2_end_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, int begin, int end,
+                             const const_subiterator1_type &it1_begin, const const_subiterator1_type &it1_end,
+                             const const_subiterator2_type &it2_begin, const const_subiterator2_type &it2_end):
+                container_const_reference<self_type> (m),
+                begin_ (begin), end_ (end), current_ (begin),
+                it1_begin_ (it1_begin), it1_end_ (it1_end), it1_ (it1_begin_),
+                it2_begin_ (it2_begin), it2_end_ (it2_end), it2_ (it2_begin_) {
+                if (current_ == 0 && it1_ == it1_end_)
+                    current_ = 1;
+                if (current_ == 1 && it2_ == it2_end_)
+                    current_ = 0;
+                if ((current_ == 0 && it1_ == it1_end_) ||
+                    (current_ == 1 && it2_ == it2_end_))
+                    current_ = end_;
+                BOOST_UBLAS_CHECK (current_ == end_ ||
+                                   (current_ == 0 && it1_ != it1_end_) ||
+                                   (current_ == 1 && it2_ != it2_end_), internal_logic ());
+            }
+            // FIXME cannot compiler
+            //  iterator2 does not have these members!
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()),
+                begin_ (it.begin_), end_ (it.end_), current_ (it.current_),
+                it1_begin_ (it.it1_begin_), it1_end_ (it.it1_end_), it1_ (it.it1_),
+                it2_begin_ (it.it2_begin_), it2_end_ (it.it2_end_), it2_ (it.it2_) {
+                BOOST_UBLAS_CHECK (current_ == end_ ||
+                                   (current_ == 0 && it1_ != it1_end_) ||
+                                   (current_ == 1 && it2_ != it2_end_), internal_logic ());
+            }
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    ++ it1_;
+                    if (it1_ == it1_end_ && end_ == 1) {
+                        it2_ = it2_begin_;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    ++ it2_;
+                    if (it2_ == it2_end_ && end_ == 0) {
+                        it1_ = it1_begin_;
+                        current_ = 0;
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    if (it1_ == it1_begin_ && begin_ == 1) {
+                        it2_ = it2_end_;
+                        BOOST_UBLAS_CHECK (it2_ != it2_begin_, internal_logic ());
+                        -- it2_;
+                        current_ = 1;
+                    } else {
+                        -- it1_;
+                    }
+                } else /* if (current_ == 1) */ {
+                    if (it2_ == it2_begin_ && begin_ == 0) {
+                        it1_ = it1_end_;
+                        BOOST_UBLAS_CHECK (it1_ != it1_begin_, internal_logic ());
+                        -- it1_;
+                        current_ = 0;
+                    } else {
+                        -- it2_;
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    size_type d = (std::min) (n, it1_end_ - it1_);
+                    it1_ += d;
+                    n -= d;
+                    if (n > 0 || (end_ == 1 && it1_ == it1_end_)) {
+                        BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
+                        d = (std::min) (n, it2_end_ - it2_begin_);
+                        it2_ = it2_begin_ + d;
+                        n -= d;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    size_type d = (std::min) (n, it2_end_ - it2_);
+                    it2_ += d;
+                    n -= d;
+                    if (n > 0 || (end_ == 0 && it2_ == it2_end_)) {
+                        BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
+                        d = (std::min) (n, it1_end_ - it1_begin_);
+                        it1_ = it1_begin_ + d;
+                        n -= d;
+                        current_ = 0;
+                    }
+                }
+                BOOST_UBLAS_CHECK (n == 0, external_logic ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    size_type d = (std::min) (n, it1_ - it1_begin_);
+                    it1_ -= d;
+                    n -= d;
+                    if (n > 0) {
+                        BOOST_UBLAS_CHECK (end_ == 1, external_logic ());
+                        d = (std::min) (n, it2_end_ - it2_begin_);
+                        it2_ = it2_end_ - d;
+                        n -= d;
+                        current_ = 1;
+                    }
+                } else /* if (current_ == 1) */ {
+                    size_type d = (std::min) (n, it2_ - it2_begin_);
+                    it2_ -= d;
+                    n -= d;
+                    if (n > 0) {
+                        BOOST_UBLAS_CHECK (end_ == 0, external_logic ());
+                        d = (std::min) (n, it1_end_ - it1_begin_);
+                        it1_ = it1_end_ - d;
+                        n -= d;
+                        current_ = 0;
+                    }
+                }
+                BOOST_UBLAS_CHECK (n == 0, external_logic ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
+                if (current_ == 0 && it.current_ == 0) {
+                    return it1_ - it.it1_;
+                } else if (current_ == 0 && it.current_ == 1) {
+                    if (end_ == 1 && it.end_ == 1) {
+                        return (it1_ - it.it1_end_) + (it.it2_begin_ - it.it2_);
+                    } else /* if (end_ == 0 && it.end_ == 0) */ {
+                        return (it1_ - it.it1_begin_) + (it.it2_end_ - it.it2_);
+                    }
+
+                } else if (current_ == 1 && it.current_ == 0) {
+                    if (end_ == 1 && it.end_ == 1) {
+                        return (it2_ - it.it2_begin_) + (it.it1_end_ - it.it1_);
+                    } else /* if (end_ == 0 && it.end_ == 0) */ {
+                        return (it2_ - it.it2_end_) + (it.it1_begin_ - it.it1_);
+                    }
+                }
+                /* current_ == 1 && it.current_ == 1 */ {
+                    return it2_ - it.it2_;
+                }
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    return *it1_;
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    return *it2_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    return it1_.index2 ();
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    return it2_.index1 ();
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                if (current_ == 0) {
+                    BOOST_UBLAS_CHECK (it1_ != it1_end_, internal_logic ());
+                    return it1_.index1 ();
+                } else /* if (current_ == 1) */ {
+                    BOOST_UBLAS_CHECK (it2_ != it2_end_, internal_logic ());
+                    return it2_.index2 ();
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                begin_ = it.begin_;
+                end_ = it.end_;
+                current_ = it.current_;
+                it1_begin_ = it.it1_begin_;
+                it1_end_ = it.it1_end_;
+                it1_ = it.it1_;
+                it2_begin_ = it.it2_begin_;
+                it2_end_ = it.it2_end_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (current_ == 0 || current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (it.current_ == 0 || it.current_ == 1, internal_logic ());
+                BOOST_UBLAS_CHECK (/* begin_ == it.begin_ && */ end_ == it.end_, internal_logic ());
+                return (current_ == 0 && it.current_ == 0 && it1_ == it.it1_) ||
+                       (current_ == 1 && it.current_ == 1 && it2_ == it.it2_);
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it - *this > 0;
+            }
+
+        private:
+            int begin_;
+            int end_;
+            int current_;
+            const_subiterator1_type it1_begin_;
+            const_subiterator1_type it1_end_;
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_begin_;
+            const_subiterator2_type it2_end_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<symmetric_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               iterator2, value_type> {
+        public:
+            typedef typename subiterator2_type::value_type value_type;
+            typedef typename subiterator2_type::difference_type difference_type;
+            typedef typename subiterator2_type::reference reference;
+            typedef typename subiterator2_type::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, const subiterator2_type &it2):
+                container_reference<self_type> (m), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return *it2_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it2_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            subiterator2_type it2_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2 ());
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        matrix_closure_type data_;
+    };
+
+    // Specialization for temporary_traits
+    template <class M, class TRI>
+    struct vector_temporary_traits< symmetric_adaptor<M, TRI> >
+    : vector_temporary_traits< M > {} ;
+    template <class M, class TRI>
+    struct vector_temporary_traits< const symmetric_adaptor<M, TRI> >
+    : vector_temporary_traits< M > {} ;
+
+    template <class M, class TRI>
+    struct matrix_temporary_traits< symmetric_adaptor<M, TRI> >
+    : matrix_temporary_traits< M > {} ;
+    template <class M, class TRI>
+    struct matrix_temporary_traits< const symmetric_adaptor<M, TRI> >
+    : matrix_temporary_traits< M > {} ;
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/tags.hpp b/include/boost/numeric/ublas/tags.hpp
new file mode 100644
index 0000000..27351bb
--- /dev/null
+++ b/include/boost/numeric/ublas/tags.hpp
@@ -0,0 +1,37 @@
+/**
+ * -*- c++ -*-
+ *
+ * \file tags.hpp
+ *
+ * \brief Tags.
+ *
+ * Copyright (c) 2009, Marco Guazzone
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Marco Guazzone, marco.guazzone@gmail.com
+ */
+
+#ifndef BOOST_NUMERIC_UBLAS_TAG_HPP
+#define BOOST_NUMERIC_UBLAS_TAG_HPP
+
+
+namespace boost { namespace numeric { namespace ublas { namespace tag {
+
+/// \brief Tag for the major dimension.
+struct major {};
+
+
+/// \brief Tag for the minor dimension.
+struct minor {};
+
+
+/// \brief Tag for the leading dimension.
+struct leading {};
+
+}}}} // Namespace boost::numeric::ublas::tag
+
+
+#endif // BOOST_NUMERIC_UBLAS_TAG_HPP
diff --git a/include/boost/numeric/ublas/traits.hpp b/include/boost/numeric/ublas/traits.hpp
new file mode 100644
index 0000000..ecd52ca
--- /dev/null
+++ b/include/boost/numeric/ublas/traits.hpp
@@ -0,0 +1,759 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_TRAITS_
+#define _BOOST_UBLAS_TRAITS_
+
+#include <iterator>
+#include <complex>
+#include <boost/config/no_tr1/cmath.hpp>
+
+#include <boost/numeric/ublas/detail/config.hpp>
+#include <boost/numeric/ublas/detail/iterator.hpp>
+#include <boost/numeric/ublas/detail/returntype_deduction.hpp>
+#ifdef BOOST_UBLAS_USE_INTERVAL
+#include <boost/numeric/interval.hpp>
+#endif
+
+#include <boost/type_traits.hpp>
+#include <complex>
+#include <boost/typeof/typeof.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_float.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
+#include <boost/mpl/and.hpp>
+
+// anonymous namespace to avoid ADL issues
+namespace {
+  template<class T> T boost_numeric_ublas_sqrt (const T& t) {
+    using namespace std;
+    // we'll find either std::sqrt or else another version via ADL:
+    return sqrt (t);
+  }
+
+template<typename T>
+inline typename boost::disable_if<
+    boost::is_unsigned<T>, T >::type
+    boost_numeric_ublas_abs (const T &t ) {
+        using namespace std;
+        return abs( t );
+    }
+
+template<typename T>
+inline typename boost::enable_if<
+    boost::is_unsigned<T>, T >::type
+    boost_numeric_ublas_abs (const T &t ) {
+        return t;
+    }
+}
+
+namespace boost { namespace numeric { namespace ublas {
+
+
+    template<typename R, typename I>
+    typename boost::enable_if<
+      mpl::and_<
+        boost::is_float<R>,
+        boost::is_integral<I>
+        >,
+      std::complex<R> >::type inline operator+ (I in1, std::complex<R> const& in2 ) {
+      return R (in1) + in2;
+    }
+
+    template<typename R, typename I>
+    typename boost::enable_if<
+      mpl::and_<
+        boost::is_float<R>,
+        boost::is_integral<I>
+        >,
+      std::complex<R> >::type inline operator+ (std::complex<R> const& in1, I in2) {
+      return in1 + R (in2);
+    }
+
+    template<typename R, typename I>
+    typename boost::enable_if<
+      mpl::and_<
+        boost::is_float<R>,
+        boost::is_integral<I>
+        >,
+      std::complex<R> >::type inline operator- (I in1, std::complex<R> const& in2) {
+      return R (in1) - in2;
+    }
+
+    template<typename R, typename I>
+    typename boost::enable_if<
+      mpl::and_<
+        boost::is_float<R>,
+        boost::is_integral<I>
+        >,
+      std::complex<R> >::type inline operator- (std::complex<R> const& in1, I in2) {
+      return in1 - R (in2);
+    }
+
+    template<typename R, typename I>
+    typename boost::enable_if<
+      mpl::and_<
+        boost::is_float<R>,
+        boost::is_integral<I>
+        >,
+      std::complex<R> >::type inline operator* (I in1, std::complex<R> const& in2) {
+      return R (in1) * in2;
+    }
+
+    template<typename R, typename I>
+    typename boost::enable_if<
+      mpl::and_<
+        boost::is_float<R>,
+        boost::is_integral<I>
+        >,
+      std::complex<R> >::type inline operator* (std::complex<R> const& in1, I in2) {
+      return in1 * R(in2);
+    }
+
+    template<typename R, typename I>
+    typename boost::enable_if<
+      mpl::and_<
+        boost::is_float<R>,
+        boost::is_integral<I>
+        >,
+      std::complex<R> >::type inline operator/ (I in1, std::complex<R> const& in2) {
+      return R(in1) / in2;
+    }
+
+    template<typename R, typename I>
+    typename boost::enable_if<
+      mpl::and_<
+        boost::is_float<R>,
+        boost::is_integral<I>
+        >,
+      std::complex<R> >::type inline operator/ (std::complex<R> const& in1, I in2) {
+      return in1 / R (in2);
+    }
+
+    // Use Joel de Guzman's return type deduction
+    // uBLAS assumes a common return type for all binary arithmetic operators
+    template<class X, class Y>
+    struct promote_traits {
+        typedef type_deduction_detail::base_result_of<X, Y> base_type;
+        static typename base_type::x_type x;
+        static typename base_type::y_type y;
+        static const std::size_t size = sizeof (
+                type_deduction_detail::test<
+                    typename base_type::x_type
+                  , typename base_type::y_type
+                >(x + y)     // Use x+y to stand of all the arithmetic actions
+            );
+
+        static const std::size_t index = (size / sizeof (char)) - 1;
+        typedef typename mpl::at_c<
+            typename base_type::types, index>::type id;
+        typedef typename id::type promote_type;
+    };
+
+
+
+    // Type traits - generic numeric properties and functions
+    template<class T>
+    struct type_traits;
+        
+    // Define properties for a generic scalar type
+    template<class T>
+    struct scalar_traits {
+        typedef scalar_traits<T> self_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+
+        typedef T real_type;
+        typedef real_type precision_type;       // we do not know what type has more precision then the real_type
+
+        static const unsigned plus_complexity = 1;
+        static const unsigned multiplies_complexity = 1;
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type real (const_reference t) {
+                return t;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type imag (const_reference /*t*/) {
+                return 0;
+        }
+        static
+        BOOST_UBLAS_INLINE
+        value_type conj (const_reference t) {
+                return t;
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type type_abs (const_reference t) {
+            return boost_numeric_ublas_abs (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        value_type type_sqrt (const_reference t) {
+            // force a type conversion back to value_type for intgral types
+            return value_type (boost_numeric_ublas_sqrt (t));
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_1 (const_reference t) {
+            return self_type::type_abs (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_2 (const_reference t) {
+            return self_type::type_abs (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_inf (const_reference t) {
+            return self_type::type_abs (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        bool equals (const_reference t1, const_reference t2) {
+            return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
+                   (std::max) ((std::max) (self_type::norm_inf (t1),
+                                       self_type::norm_inf (t2)),
+                             BOOST_UBLAS_TYPE_CHECK_MIN);
+        }
+    };
+
+    // Define default type traits, assume T is a scalar type
+    template<class T>
+    struct type_traits : scalar_traits <T> {
+        typedef type_traits<T> self_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+
+        typedef T real_type;
+        typedef real_type precision_type;
+        static const unsigned multiplies_complexity = 1;
+
+    };
+
+    // Define real type traits
+    template<>
+    struct type_traits<float> : scalar_traits<float> {
+        typedef type_traits<float> self_type;
+        typedef float value_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef value_type real_type;
+        typedef double precision_type;
+    };
+    template<>
+    struct type_traits<double> : scalar_traits<double> {
+        typedef type_traits<double> self_type;
+        typedef double value_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef value_type real_type;
+        typedef long double precision_type;
+    };
+    template<>
+    struct type_traits<long double>  : scalar_traits<long double> {
+        typedef type_traits<long double> self_type;
+        typedef long double value_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef value_type real_type;
+        typedef value_type precision_type;
+    };
+
+    // Define properties for a generic complex type
+    template<class T>
+    struct complex_traits {
+        typedef complex_traits<T> self_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+
+        typedef typename T::value_type real_type;
+        typedef real_type precision_type;       // we do not know what type has more precision then the real_type
+
+        static const unsigned plus_complexity = 2;
+        static const unsigned multiplies_complexity = 6;
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type real (const_reference t) {
+                return std::real (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type imag (const_reference t) {
+                return std::imag (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        value_type conj (const_reference t) {
+                return std::conj (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type type_abs (const_reference t) {
+                return abs (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        value_type type_sqrt (const_reference t) {
+                return sqrt (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_1 (const_reference t) {
+            return self_type::type_abs (t);
+            // original computation has been replaced because a complex number should behave like a scalar type
+            // return type_traits<real_type>::type_abs (self_type::real (t)) +
+            //       type_traits<real_type>::type_abs (self_type::imag (t));
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_2 (const_reference t) {
+            return self_type::type_abs (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_inf (const_reference t) {
+            return self_type::type_abs (t);
+            // original computation has been replaced because a complex number should behave like a scalar type
+            // return (std::max) (type_traits<real_type>::type_abs (self_type::real (t)),
+            //                 type_traits<real_type>::type_abs (self_type::imag (t)));
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        bool equals (const_reference t1, const_reference t2) {
+            return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
+                   (std::max) ((std::max) (self_type::norm_inf (t1),
+                                       self_type::norm_inf (t2)),
+                             BOOST_UBLAS_TYPE_CHECK_MIN);
+        }
+    };
+    
+    // Define complex type traits
+    template<>
+    struct type_traits<std::complex<float> > : complex_traits<std::complex<float> >{
+        typedef type_traits<std::complex<float> > self_type;
+        typedef std::complex<float> value_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef float real_type;
+        typedef std::complex<double> precision_type;
+
+    };
+    template<>
+    struct type_traits<std::complex<double> > : complex_traits<std::complex<double> >{
+        typedef type_traits<std::complex<double> > self_type;
+        typedef std::complex<double> value_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef double real_type;
+        typedef std::complex<long double> precision_type;
+    };
+    template<>
+    struct type_traits<std::complex<long double> > : complex_traits<std::complex<long double> > {
+        typedef type_traits<std::complex<long double> > self_type;
+        typedef std::complex<long double> value_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef long double real_type;
+        typedef value_type precision_type;
+    };
+
+#ifdef BOOST_UBLAS_USE_INTERVAL
+    // Define scalar interval type traits
+    template<>
+    struct type_traits<boost::numeric::interval<float> > : scalar_traits<boost::numeric::interval<float> > {
+        typedef type_traits<boost::numeric::interval<float> > self_type;
+        typedef boost::numeric::interval<float> value_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef value_type real_type;
+        typedef boost::numeric::interval<double> precision_type;
+
+    };
+    template<>
+    struct type_traits<boost::numeric::interval<double> > : scalar_traits<boost::numeric::interval<double> > {
+        typedef type_traits<boost::numeric::interval<double> > self_type;
+        typedef boost::numeric::interval<double> value_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef value_type real_type;
+        typedef boost::numeric::interval<long double> precision_type;
+    };
+    template<>
+    struct type_traits<boost::numeric::interval<long double> > : scalar_traits<boost::numeric::interval<long double> > {
+        typedef type_traits<boost::numeric::interval<long double> > self_type;
+        typedef boost::numeric::interval<long double> value_type;
+        typedef const value_type &const_reference;
+        typedef value_type &reference;
+        typedef value_type real_type;
+        typedef value_type precision_type;
+    };
+#endif
+
+
+    // Storage tags -- hierarchical definition of storage characteristics
+
+    struct unknown_storage_tag {};
+    struct sparse_proxy_tag: public unknown_storage_tag {};
+    struct sparse_tag: public sparse_proxy_tag {};
+    struct packed_proxy_tag: public sparse_proxy_tag {};
+    struct packed_tag: public packed_proxy_tag {};
+    struct dense_proxy_tag: public packed_proxy_tag {};
+    struct dense_tag: public dense_proxy_tag {};
+
+    template<class S1, class S2>
+    struct storage_restrict_traits {
+        typedef S1 storage_category;
+    };
+
+    template<>
+    struct storage_restrict_traits<sparse_tag, dense_proxy_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+    template<>
+    struct storage_restrict_traits<sparse_tag, packed_proxy_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+    template<>
+    struct storage_restrict_traits<sparse_tag, sparse_proxy_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<>
+    struct storage_restrict_traits<packed_tag, dense_proxy_tag> {
+        typedef packed_proxy_tag storage_category;
+    };
+    template<>
+    struct storage_restrict_traits<packed_tag, packed_proxy_tag> {
+        typedef packed_proxy_tag storage_category;
+    };
+    template<>
+    struct storage_restrict_traits<packed_tag, sparse_proxy_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<>
+    struct storage_restrict_traits<packed_proxy_tag, sparse_proxy_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<>
+    struct storage_restrict_traits<dense_tag, dense_proxy_tag> {
+        typedef dense_proxy_tag storage_category;
+    };
+    template<>
+    struct storage_restrict_traits<dense_tag, packed_proxy_tag> {
+        typedef packed_proxy_tag storage_category;
+    };
+    template<>
+    struct storage_restrict_traits<dense_tag, sparse_proxy_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+    template<>
+    struct storage_restrict_traits<dense_proxy_tag, packed_proxy_tag> {
+        typedef packed_proxy_tag storage_category;
+    };
+    template<>
+    struct storage_restrict_traits<dense_proxy_tag, sparse_proxy_tag> {
+        typedef sparse_proxy_tag storage_category;
+    };
+
+
+    // Iterator tags -- hierarchical definition of storage characteristics
+
+    struct sparse_bidirectional_iterator_tag : public std::bidirectional_iterator_tag {};
+    struct packed_random_access_iterator_tag : public std::random_access_iterator_tag {};
+    struct dense_random_access_iterator_tag : public packed_random_access_iterator_tag {};
+
+    // Thanks to Kresimir Fresl for convincing Comeau with iterator_base_traits ;-)
+    template<class IC>
+    struct iterator_base_traits {};
+
+    template<>
+    struct iterator_base_traits<std::forward_iterator_tag> {
+        template<class I, class T>
+        struct iterator_base {
+            typedef forward_iterator_base<std::forward_iterator_tag, I, T> type;
+        };
+    };
+
+    template<>
+    struct iterator_base_traits<std::bidirectional_iterator_tag> {
+        template<class I, class T>
+        struct iterator_base {
+            typedef bidirectional_iterator_base<std::bidirectional_iterator_tag, I, T> type;
+        };
+    };
+    template<>
+    struct iterator_base_traits<sparse_bidirectional_iterator_tag> {
+        template<class I, class T>
+        struct iterator_base {
+            typedef bidirectional_iterator_base<sparse_bidirectional_iterator_tag, I, T> type;
+        };
+    };
+
+    template<>
+    struct iterator_base_traits<std::random_access_iterator_tag> {
+        template<class I, class T>
+        struct iterator_base {
+            typedef random_access_iterator_base<std::random_access_iterator_tag, I, T> type;
+        };
+    };
+    template<>
+    struct iterator_base_traits<packed_random_access_iterator_tag> {
+        template<class I, class T>
+        struct iterator_base {
+            typedef random_access_iterator_base<packed_random_access_iterator_tag, I, T> type;
+        };
+    };
+    template<>
+    struct iterator_base_traits<dense_random_access_iterator_tag> {
+        template<class I, class T>
+        struct iterator_base {
+            typedef random_access_iterator_base<dense_random_access_iterator_tag, I, T> type;
+        };
+    };
+
+    template<class I1, class I2>
+    struct iterator_restrict_traits {
+        typedef I1 iterator_category;
+    };
+
+    template<>
+    struct iterator_restrict_traits<packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_bidirectional_iterator_tag iterator_category;
+    };
+    template<>
+    struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag> {
+        typedef sparse_bidirectional_iterator_tag iterator_category;
+    };
+
+    template<>
+    struct iterator_restrict_traits<dense_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
+        typedef sparse_bidirectional_iterator_tag iterator_category;
+    };
+    template<>
+    struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, dense_random_access_iterator_tag> {
+        typedef sparse_bidirectional_iterator_tag iterator_category;
+    };
+
+    template<>
+    struct iterator_restrict_traits<dense_random_access_iterator_tag, packed_random_access_iterator_tag> {
+        typedef packed_random_access_iterator_tag iterator_category;
+    };
+    template<>
+    struct iterator_restrict_traits<packed_random_access_iterator_tag, dense_random_access_iterator_tag> {
+        typedef packed_random_access_iterator_tag iterator_category;
+    };
+
+    template<class I>
+    BOOST_UBLAS_INLINE
+    void increment (I &it, const I &it_end, typename I::difference_type compare, packed_random_access_iterator_tag) {
+        it += (std::min) (compare, it_end - it);
+    }
+    template<class I>
+    BOOST_UBLAS_INLINE
+    void increment (I &it, const I &/* it_end */, typename I::difference_type /* compare */, sparse_bidirectional_iterator_tag) {
+        ++ it;
+    }
+    template<class I>
+    BOOST_UBLAS_INLINE
+    void increment (I &it, const I &it_end, typename I::difference_type compare) {
+        increment (it, it_end, compare, typename I::iterator_category ());
+    }
+
+    template<class I>
+    BOOST_UBLAS_INLINE
+    void increment (I &it, const I &it_end) {
+#if BOOST_UBLAS_TYPE_CHECK
+        I cit (it);
+        while (cit != it_end) {
+            BOOST_UBLAS_CHECK (*cit == typename I::value_type/*zero*/(), internal_logic ());
+            ++ cit;
+        }
+#endif
+        it = it_end;
+    }
+
+    namespace detail {
+
+        // specialisation which define whether a type has a trivial constructor
+        // or not. This is used by array types.
+        template<typename T>
+        struct has_trivial_constructor : public boost::has_trivial_constructor<T> {};
+
+        template<typename T>
+        struct has_trivial_destructor : public boost::has_trivial_destructor<T> {};
+
+        template<typename FLT>
+        struct has_trivial_constructor<std::complex<FLT> > : public has_trivial_constructor<FLT> {};
+        
+        template<typename FLT>
+        struct has_trivial_destructor<std::complex<FLT> > : public has_trivial_destructor<FLT> {};
+
+    }
+
+
+    /**  \brief Traits class to extract type information from a constant matrix or vector CONTAINER.
+     *
+     */
+    template < class E >
+    struct container_view_traits {
+        /// type of indices
+        typedef typename E::size_type             size_type;
+        /// type of differences of indices
+        typedef typename E::difference_type       difference_type;
+
+        /// storage category: \c unknown_storage_tag, \c dense_tag, \c packed_tag, ...
+        typedef typename E::storage_category      storage_category;
+
+        /// type of elements
+        typedef typename E::value_type            value_type;
+        /// const reference to an element
+        typedef typename E::const_reference       const_reference;
+  
+        /// type used in expressions to mark a reference to this class (usually a const container_reference<const E> or the class itself)
+        typedef typename E::const_closure_type    const_closure_type;
+    };
+
+    /**  \brief Traits class to extract additional type information from a mutable matrix or vector CONTAINER.
+     *
+     */
+    template < class E >
+    struct mutable_container_traits {
+        /// reference to an element
+        typedef typename E::reference             reference;
+  
+        /// type used in expressions to mark a reference to this class (usually a container_reference<E> or the class itself)
+        typedef typename E::closure_type          closure_type;
+    };
+
+    /**  \brief Traits class to extract type information from a matrix or vector CONTAINER.
+     *
+     */
+    template < class E >
+    struct container_traits 
+        : container_view_traits<E>, mutable_container_traits<E> {
+
+    };
+
+
+    /**  \brief Traits class to extract type information from a constant MATRIX.
+     *
+     */
+    template < class MATRIX >
+    struct matrix_view_traits : container_view_traits <MATRIX> {
+
+        /// orientation of the matrix, either \c row_major_tag, \c column_major_tag or \c unknown_orientation_tag
+        typedef typename MATRIX::orientation_category  orientation_category;
+  
+        /// row iterator for the matrix
+        typedef typename MATRIX::const_iterator1  const_iterator1;
+
+        /// column iterator for the matrix
+        typedef typename MATRIX::const_iterator2  const_iterator2;
+    };
+
+    /**  \brief Traits class to extract additional type information from a mutable MATRIX.
+     *
+     */
+    template < class MATRIX >
+    struct mutable_matrix_traits 
+        : mutable_container_traits <MATRIX> {
+
+        /// row iterator for the matrix
+        typedef typename MATRIX::iterator1  iterator1;
+
+        /// column iterator for the matrix
+        typedef typename MATRIX::iterator2  iterator2;
+    };
+
+
+    /**  \brief Traits class to extract type information from a MATRIX.
+     *
+     */
+    template < class MATRIX >
+    struct matrix_traits 
+        : matrix_view_traits <MATRIX>, mutable_matrix_traits <MATRIX> {
+    };
+
+    /**  \brief Traits class to extract type information from a VECTOR.
+     *
+     */
+    template < class VECTOR >
+    struct vector_view_traits : container_view_traits <VECTOR> {
+
+        /// iterator for the VECTOR
+        typedef typename VECTOR::const_iterator  const_iterator;
+
+        /// iterator pointing to the first element
+        static
+        const_iterator begin(const VECTOR & v) {
+            return v.begin();
+        }
+        /// iterator pointing behind the last element
+        static
+        const_iterator end(const VECTOR & v) {
+            return v.end();
+        }
+
+    };
+
+    /**  \brief Traits class to extract type information from a VECTOR.
+     *
+     */
+    template < class VECTOR >
+    struct mutable_vector_traits : mutable_container_traits <VECTOR> {
+        /// iterator for the VECTOR
+        typedef typename VECTOR::iterator  iterator;
+
+        /// iterator pointing to the first element
+        static
+        iterator begin(VECTOR & v) {
+            return v.begin();
+        }
+
+        /// iterator pointing behind the last element
+        static
+        iterator end(VECTOR & v) {
+            return v.end();
+        }
+    };
+
+    /**  \brief Traits class to extract type information from a VECTOR.
+     *
+     */
+    template < class VECTOR >
+    struct vector_traits 
+        : vector_view_traits <VECTOR>, mutable_vector_traits <VECTOR> {
+    };
+
+
+    // Note: specializations for T[N] and T[M][N] have been moved to traits/c_array.hpp
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/traits/c_array.hpp b/include/boost/numeric/ublas/traits/c_array.hpp
new file mode 100644
index 0000000..7c571fc
--- /dev/null
+++ b/include/boost/numeric/ublas/traits/c_array.hpp
@@ -0,0 +1,110 @@
+/**
+ * -*- c++ -*-
+ *
+ * \file c_array.hpp
+ *
+ * \brief provides specializations of matrix and vector traits for c arrays and c matrices.
+ *
+ * Copyright (c) 2009, Gunter Winkler
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Gunter Winkler (guwi17 at gmx dot de)
+ */
+
+#ifndef BOOST_NUMERIC_UBLAS_TRAITS_C_ARRAY_HPP
+#define BOOST_NUMERIC_UBLAS_TRAITS_C_ARRAY_HPP
+
+
+#include <boost/numeric/ublas/traits.hpp>
+#include <boost/numeric/ublas/traits/const_iterator_type.hpp>
+#include <boost/numeric/ublas/traits/iterator_type.hpp>
+
+namespace boost { namespace numeric { namespace ublas {
+
+    namespace detail {
+
+    
+    
+    }
+
+
+    template < class T, int M, int N > 
+    struct matrix_view_traits < T[M][N] > {
+        typedef T              matrix_type[M][N];
+
+        typedef std::size_t          size_type;
+        typedef std::ptrdiff_t       difference_type;
+
+        typedef row_major_tag  orientation_category;
+        typedef dense_tag      storage_category;
+  
+        typedef T            value_type;
+        typedef const T      &const_reference;
+        typedef const T      *const_pointer;
+  
+        typedef const matrix_reference<const matrix_type>    const_closure_type;
+
+        typedef T row_type[N];
+
+        typedef const row_type *const_iterator1;
+        typedef const_pointer  const_iterator2;
+
+    };
+
+    template < class T, int M, int N > 
+    struct mutable_matrix_traits < T[M][N] > {
+        typedef T            matrix_type[M][N];
+
+        typedef T            *reference;
+  
+        typedef matrix_reference<matrix_type>                closure_type;
+
+    };
+
+    template < class T, int N  > 
+    struct vector_view_traits < T[N] > {
+        typedef T              vector_type[N];
+
+        typedef std::size_t          size_type;
+        typedef std::ptrdiff_t       difference_type;
+
+        typedef dense_tag      storage_category;
+  
+        typedef T            value_type;
+        typedef const T      &const_reference;
+        typedef const T      *const_pointer;
+  
+        typedef const vector_reference<const vector_type>    const_closure_type;
+
+        typedef const_pointer const_iterator;
+
+        /// iterator pointing to the first element
+        static
+        const_iterator begin(const vector_type & v) {
+            return & (v[0]);
+        }
+        /// iterator pointing behind the last element
+        static
+        const_iterator end(const vector_type & v) {
+            return & (v[N]);
+        }
+    };
+
+    template < class T, int N  > 
+    struct mutable_vector_traits < T[N] >  {
+  
+        typedef T &reference;
+        typedef T *pointer;
+        typedef vector_reference< T[N] > closure_type;
+
+    };
+
+
+
+
+}}} // Namespace boost::numeric::ublas
+
+#endif
diff --git a/include/boost/numeric/ublas/traits/const_iterator_type.hpp b/include/boost/numeric/ublas/traits/const_iterator_type.hpp
new file mode 100644
index 0000000..1beeccc
--- /dev/null
+++ b/include/boost/numeric/ublas/traits/const_iterator_type.hpp
@@ -0,0 +1,127 @@
+/**
+ * -*- c++ -*-
+ *
+ * \file const_iterator_type.hpp
+ *
+ * \brief Const iterator to a given container type.
+ *
+ * Copyright (c) 2009, Marco Guazzone
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Marco Guazzone, marco.guazzone@gmail.com
+ */
+
+
+#ifndef BOOST_NUMERIC_UBLAS_TRAITS_CONST_ITERATOR_TYPE_HPP
+#define BOOST_NUMERIC_UBLAS_TRAITS_CONST_ITERATOR_TYPE_HPP
+
+
+#include <boost/numeric/ublas/fwd.hpp>
+#include <boost/numeric/ublas/tags.hpp>
+#include <boost/numeric/ublas/traits.hpp>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    namespace detail {
+
+        /**
+         * \brief Auxiliary class for retrieving the const iterator to the given
+         *  matrix expression according its orientation and to the given dimension tag.
+         * \tparam MatrixT A model of MatrixExpression.
+         * \tparam TagT A dimension tag type (e.g., tag::major).
+         * \tparam OrientationT An orientation category type (e.g., row_major_tag).
+         */
+        template <typename MatrixT, typename TagT, typename OrientationT>
+        struct const_iterator_type_impl;
+
+
+        /// \brief Specialization of \c const_iterator_type_impl for row-major oriented
+        ///  matrices and over the major dimension.
+        template <typename MatrixT>
+        struct const_iterator_type_impl<MatrixT,tag::major,row_major_tag>
+        {
+            typedef typename matrix_view_traits<MatrixT>::const_iterator1 type;
+        };
+
+
+        /// \brief Specialization of \c const_iterator_type_impl for column-major
+        ///  oriented matrices and over the major dimension.
+        template <typename MatrixT>
+        struct const_iterator_type_impl<MatrixT,tag::major,column_major_tag>
+        {
+            typedef typename matrix_view_traits<MatrixT>::const_iterator2 type;
+        };
+
+
+        /// \brief Specialization of \c const_iterator_type_impl for row-major oriented
+        ///  matrices and over the minor dimension.
+        template <typename MatrixT>
+        struct const_iterator_type_impl<MatrixT,tag::minor,row_major_tag>
+        {
+            typedef typename matrix_view_traits<MatrixT>::const_iterator2 type;
+        };
+
+
+        /// \brief Specialization of \c const_iterator_type_impl for column-major
+        ///  oriented matrices and over the minor dimension.
+        template <typename MatrixT>
+        struct const_iterator_type_impl<MatrixT,tag::minor,column_major_tag>
+        {
+            typedef typename matrix_view_traits<MatrixT>::const_iterator1 type;
+        };
+
+    } // Namespace detail
+
+
+    /**
+     * \brief A const iterator for the given container type over the given
+     *  dimension.
+     * \tparam ContainerT A container expression type.
+     * \tparam TagT A dimension tag type (e.g., tag::major).
+     */
+    template <typename ContainerT, typename TagT=void>
+    struct const_iterator_type;
+
+
+    /**
+     * \brief Specialization of \c const_iterator_type for vector expressions.
+     * \tparam VectorT A model of VectorExpression type.
+     */
+    template <typename VectorT>
+    struct const_iterator_type<VectorT, void>
+    {
+        typedef typename vector_view_traits<VectorT>::const_iterator type;
+    };
+
+
+    /**
+     * \brief Specialization of \c const_iterator_type for matrix expressions and
+     *  over the major dimension.
+     * \tparam MatrixT A model of MatrixExpression type.
+     */
+    template <typename MatrixT>
+    struct const_iterator_type<MatrixT,tag::major>
+    {
+        typedef typename detail::const_iterator_type_impl<MatrixT,tag::minor,typename matrix_view_traits<MatrixT>::orientation_category>::type type;
+    };
+
+
+    /**
+     * \brief Specialization of \c const_iterator_type for matrix expressions and
+     *  over the minor dimension.
+     * \tparam MatrixT A model of MatrixExpression type.
+     */
+    template <typename MatrixT>
+    struct const_iterator_type<MatrixT,tag::minor>
+    {
+        typedef typename detail::const_iterator_type_impl<MatrixT,tag::minor,typename matrix_view_traits<MatrixT>::orientation_category>::type type;
+    };
+
+}}} // Namespace boost::numeric::ublas
+
+
+#endif // BOOST_NUMERIC_UBLAS_TRAITS_CONST_ITERATOR_TYPE_HPP
diff --git a/include/boost/numeric/ublas/traits/iterator_type.hpp b/include/boost/numeric/ublas/traits/iterator_type.hpp
new file mode 100644
index 0000000..c706b4d
--- /dev/null
+++ b/include/boost/numeric/ublas/traits/iterator_type.hpp
@@ -0,0 +1,126 @@
+/**
+ * -*- c++ -*-
+ *
+ * \file iterator_type.hpp
+ *
+ * \brief Iterator to a given container type.
+ *
+ * Copyright (c) 2009, Marco Guazzone
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Marco Guazzone, marco.guazzone@gmail.com
+ */
+
+
+#ifndef BOOST_NUMERIC_UBLAS_TRAITS_ITERATOR_TYPE_HPP
+#define BOOST_NUMERIC_UBLAS_TRAITS_ITERATOR_TYPE_HPP
+
+
+#include <boost/numeric/ublas/fwd.hpp>
+#include <boost/numeric/ublas/traits.hpp>
+#include <boost/numeric/ublas/tags.hpp>
+
+
+namespace boost { namespace numeric { namespace ublas {
+
+    namespace detail {
+
+        /**
+         * \brief Auxiliary class for retrieving the iterator to the given
+         *  matrix expression according its orientation and to the given dimension tag.
+         * \tparam MatrixT A model of MatrixExpression.
+         * \tparam TagT A dimension tag type (e.g., tag::major).
+         * \tparam OrientationT An orientation category type (e.g., row_major_tag).
+         */
+        template <typename MatrixT, typename TagT, typename OrientationT>
+        struct iterator_type_impl;
+
+
+        /// \brief Specialization of \c iterator_type_impl for row-major oriented
+        ///  matrices and over the major dimension.
+        template <typename MatrixT>
+        struct iterator_type_impl<MatrixT,tag::major,row_major_tag>
+        {
+            typedef typename matrix_traits<MatrixT>::iterator1 type;
+        };
+
+
+        /// \brief Specialization of \c iterator_type_impl for column-major oriented
+        ///  matrices and over the major dimension.
+        template <typename MatrixT>
+        struct iterator_type_impl<MatrixT,tag::major,column_major_tag>
+        {
+            typedef typename matrix_traits<MatrixT>::iterator2 type;
+        };
+
+
+        /// \brief Specialization of \c iterator_type_impl for row-major oriented
+        ///  matrices and over the minor dimension.
+        template <typename MatrixT>
+        struct iterator_type_impl<MatrixT,tag::minor,row_major_tag>
+        {
+            typedef typename matrix_traits<MatrixT>::iterator2 type;
+        };
+
+
+        /// \brief Specialization of \c iterator_type_impl for column-major oriented
+        ///  matrices and over the minor dimension.
+        template <typename MatrixT>
+        struct iterator_type_impl<MatrixT,tag::minor,column_major_tag>
+        {
+            typedef typename matrix_traits<MatrixT>::iterator1 type;
+        };
+
+    } // Namespace detail
+
+
+    /**
+     * \brief A iterator for the given container type over the given dimension.
+     * \tparam ContainerT A container expression type.
+     * \tparam TagT A dimension tag type (e.g., tag::major).
+     */
+    template <typename ContainerT, typename TagT=void>
+    struct iterator_type;
+
+
+    /**
+     * \brief Specialization of \c iterator_type for vector expressions.
+     * \tparam VectorT A model of VectorExpression type.
+     */
+    template <typename VectorT>
+    struct iterator_type<VectorT, void>
+    {
+        typedef typename vector_traits<VectorT>::iterator type;
+    };
+
+
+    /**
+     * \brief Specialization of \c iterator_type for matrix expressions and
+     *  over the major dimension.
+     * \tparam MatrixT A model of MatrixExpression type.
+     */
+    template <typename MatrixT>
+    struct iterator_type<MatrixT,tag::major>
+    {
+        typedef typename detail::iterator_type_impl<MatrixT,tag::major,typename matrix_traits<MatrixT>::orientation_category>::type type;
+    };
+
+
+    /**
+     * \brief Specialization of \c iterator_type for matrix expressions and
+     *  over the minor dimension.
+     * \tparam MatrixT A model of MatrixExpression type.
+     */
+    template <typename MatrixT>
+    struct iterator_type<MatrixT,tag::minor>
+    {
+        typedef typename detail::iterator_type_impl<MatrixT,tag::minor,typename matrix_traits<MatrixT>::orientation_category>::type type;
+    };
+
+}}} // Namespace boost::numeric::ublas
+
+
+#endif // BOOST_NUMERIC_UBLAS_TRAITS_ITERATOR_TYPE_HPP
diff --git a/include/boost/numeric/ublas/triangular.hpp b/include/boost/numeric/ublas/triangular.hpp
new file mode 100644
index 0000000..61afeda
--- /dev/null
+++ b/include/boost/numeric/ublas/triangular.hpp
@@ -0,0 +1,2775 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_TRIANGULAR_
+#define _BOOST_UBLAS_TRIANGULAR_
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/detail/temporary.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+
+    namespace detail {
+        using namespace boost::numeric::ublas;
+
+        // Matrix resizing algorithm
+        template <class L, class T, class M>
+        BOOST_UBLAS_INLINE
+        void matrix_resize_preserve (M& m, M& temporary) {
+            typedef L layout_type;
+            typedef T triangular_type;
+            typedef typename M::size_type size_type;
+            const size_type msize1 (m.size1 ());        // original size
+            const size_type msize2 (m.size2 ());
+            const size_type size1 (temporary.size1 ());    // new size is specified by temporary
+            const size_type size2 (temporary.size2 ());
+            // Common elements to preserve
+            const size_type size1_min = (std::min) (size1, msize1);
+            const size_type size2_min = (std::min) (size2, msize2);
+            // Order for major and minor sizes
+            const size_type major_size = layout_type::size_M (size1_min, size2_min);
+            const size_type minor_size = layout_type::size_m (size1_min, size2_min);
+            // Indexing copy over major
+            for (size_type major = 0; major != major_size; ++major) {
+                for (size_type minor = 0; minor != minor_size; ++minor) {
+                        // find indexes - use invertability of element_ functions
+                    const size_type i1 = layout_type::index_M(major, minor);
+                    const size_type i2 = layout_type::index_m(major, minor);
+                    if ( triangular_type::other(i1,i2) ) {
+                        temporary.data () [triangular_type::element (layout_type (), i1, size1, i2, size2)] =
+                            m.data() [triangular_type::element (layout_type (), i1, msize1, i2, msize2)];
+                    }
+                }
+            }
+            m.assign_temporary (temporary);
+        }
+    }
+
+    /** \brief A triangular matrix of values of type \c T.
+     *
+     * For a \f$(n \times n )\f$-dimensional lower triangular matrix and if \f$0 \leq i < n\f$, \f$0 \leq j < n\f$ and \f$i>j\f$ holds, 
+     * \f$m_{i,j}=0\f$. Furthermore if \f$m_{i,i}=1\f$, the matrix is called unit lower triangular.
+     *
+     * For a \f$(n \times n )\f$-dimensional upper triangular matrix and if \f$0 \leq i < n\f$, \f$0 \leq j < n\f$ and \f$i<j\f$ holds, 
+     * \f$m_{i,j}=0\f$. Furthermore if \f$m_{i,i}=1\f$, the matrix is called unit upper triangular.
+     *
+     * The default storage for triangular matrices is packed. Orientation and storage can also be specified. 
+     * Default is \c row_major and and unbounded_array. It is \b not required by the storage to initialize 
+     * elements of the matrix.
+     *
+     * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
+     * \tparam TRI the type of the triangular matrix. It can either be \c lower or \c upper. Default is \c lower
+     * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
+     * \tparam A the type of Storage array. Default is \c unbounded_array
+     */
+    template<class T, class TRI, class L, class A>
+    class triangular_matrix:
+        public matrix_container<triangular_matrix<T, TRI, L, A> > {
+
+        typedef T *pointer;
+        typedef TRI triangular_type;
+        typedef L layout_type;
+        typedef triangular_matrix<T, TRI, L, A> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+        typedef T &reference;
+        typedef A array_type;
+
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef vector<T, A> vector_temporary_type;
+        typedef matrix<T, L, A> matrix_temporary_type;  // general sub-matrix
+        typedef packed_tag storage_category;
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        triangular_matrix ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0), data_ (0) {}
+        BOOST_UBLAS_INLINE
+        triangular_matrix (size_type size1, size_type size2):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), data_ (triangular_type::packed_size (layout_type (), size1, size2)) {
+        }
+        BOOST_UBLAS_INLINE
+        triangular_matrix (size_type size1, size_type size2, const array_type &data):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), data_ (data) {}
+        BOOST_UBLAS_INLINE
+        triangular_matrix (const triangular_matrix &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_matrix (const matrix_expression<AE> &ae):
+            matrix_container<self_type> (),
+            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()),
+            data_ (triangular_type::packed_size (layout_type (), size1_, size2_)) {
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const array_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            if (preserve) {
+                self_type temporary (size1, size2);
+                detail::matrix_resize_preserve<layout_type, triangular_type> (*this, temporary);
+            }
+            else {
+                data ().resize (triangular_type::packed_size (layout_type (), size1, size2));
+                size1_ = size1;
+                size2_ = size2;
+            }
+        }
+        BOOST_UBLAS_INLINE
+        void resize_packed_preserve (size_type size1, size_type size2) {
+            size1_ = size1;
+            size2_ = size2;
+            data ().resize (triangular_type::packed_size (layout_type (), size1_, size2_), value_type ());
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
+            if (triangular_type::other (i, j))
+                return data () [triangular_type::element (layout_type (), i, size1_, j, size2_)];
+            else if (triangular_type::one (i, j))
+                return one_;
+            else
+                return zero_;
+        }
+        BOOST_UBLAS_INLINE
+        reference at_element (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
+            return data () [triangular_type::element (layout_type (), i, size1_, j, size2_)];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
+            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
+            if (!triangular_type::other (i, j)) {
+                bad_index ().raise ();
+                // NEVER reached
+            }
+            return data () [triangular_type::element (layout_type (), i, size1_, j, size2_)];
+        }
+        
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        reference insert_element (size_type i, size_type j, const_reference t) {
+            return (operator () (i, j) = t);
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i, size_type j) {
+            operator () (i, j) = value_type/*zero*/();
+        }
+        
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            // data ().clear ();
+            std::fill (data ().begin (), data ().end (), value_type/*zero*/());
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        triangular_matrix &operator = (const triangular_matrix &m) {
+            size1_ = m.size1_;
+            size2_ = m.size2_;
+            data () = m.data ();
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        triangular_matrix &assign_temporary (triangular_matrix &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_matrix &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_matrix &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_matrix& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_matrix &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_matrix& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_matrix &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        triangular_matrix& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        triangular_matrix& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (triangular_matrix &m) {
+            if (this != &m) {
+                // BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ());
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                data ().swap (m.data ());
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (triangular_matrix &m1, triangular_matrix &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            if (rank == 1)
+                i = triangular_type::restrict1 (i, j, size1_, size2_);
+            if (rank == 0)
+                i = triangular_type::global_restrict1 (i, size1_, j, size2_);
+            return const_iterator1 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                i = triangular_type::mutable_restrict1 (i, j, size1_, size2_);
+            if (rank == 0)
+                i = triangular_type::global_mutable_restrict1 (i, size1_, j, size2_);
+            return iterator1 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            if (rank == 1)
+                j = triangular_type::restrict2 (i, j, size1_, size2_);
+            if (rank == 0)
+                j = triangular_type::global_restrict2 (i, size1_, j, size2_);
+            return const_iterator2 (*this, i, j);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                j = triangular_type::mutable_restrict2 (i, j, size1_, size2_);
+            if (rank == 0)
+                j = triangular_type::global_mutable_restrict2 (i, size1_, j, size2_);
+            return iterator2 (*this, i, j);
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<triangular_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename triangular_matrix::value_type value_type;
+            typedef typename triangular_matrix::difference_type difference_type;
+            typedef typename triangular_matrix::const_reference reference;
+            typedef const typename triangular_matrix::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, size_type it1, size_type it2):
+                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, it1_, 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<triangular_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename triangular_matrix::value_type value_type;
+            typedef typename triangular_matrix::difference_type difference_type;
+            typedef typename triangular_matrix::reference reference;
+            typedef typename triangular_matrix::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, size_type it1, size_type it2):
+                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                return (*this) ().find2 (1, it1_, 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                return (*this) ().find2 (1, it1_, (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1_, 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<triangular_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename triangular_matrix::value_type value_type;
+            typedef typename triangular_matrix::difference_type difference_type;
+            typedef typename triangular_matrix::const_reference reference;
+            typedef const typename triangular_matrix::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, size_type it1, size_type it2):
+                container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<triangular_matrix>,
+            public random_access_iterator_base<packed_random_access_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename triangular_matrix::value_type value_type;
+            typedef typename triangular_matrix::difference_type difference_type;
+            typedef typename triangular_matrix::reference reference;
+            typedef typename triangular_matrix::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, size_type it1, size_type it2):
+                container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                return (*this) () (it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                return (*this) ().find1 (1, 0, it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), it2_);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_;
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            size_type it1_;
+            size_type it2_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        size_type size1_;
+        size_type size2_;
+        array_type data_;
+        static const value_type zero_;
+        static const value_type one_;
+    };
+
+    template<class T, class TRI, class L, class A>
+    const typename triangular_matrix<T, TRI, L, A>::value_type triangular_matrix<T, TRI, L, A>::zero_ = value_type/*zero*/();
+    template<class T, class TRI, class L, class A>
+    const typename triangular_matrix<T, TRI, L, A>::value_type triangular_matrix<T, TRI, L, A>::one_ (1);
+
+
+    // Triangular matrix adaptor class
+    template<class M, class TRI>
+    class triangular_adaptor:
+        public matrix_expression<triangular_adaptor<M, TRI> > {
+
+        typedef triangular_adaptor<M, TRI> self_type;
+
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_expression<self_type>::operator ();
+#endif
+        typedef const M const_matrix_type;
+        typedef M matrix_type;
+        typedef TRI triangular_type;
+        typedef typename M::size_type size_type;
+        typedef typename M::difference_type difference_type;
+        typedef typename M::value_type value_type;
+        typedef typename M::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_reference,
+                                          typename M::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_closure_type,
+                                          typename M::closure_type>::type matrix_closure_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        // Replaced by _temporary_traits to avoid type requirements on M
+        //typedef typename M::vector_temporary_type vector_temporary_type;
+        //typedef typename M::matrix_temporary_type matrix_temporary_type;
+        typedef typename storage_restrict_traits<typename M::storage_category,
+                                                 packed_proxy_tag>::storage_category storage_category;
+        typedef typename M::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        triangular_adaptor (matrix_type &data):
+            matrix_expression<self_type> (),
+            data_ (data) {}
+        BOOST_UBLAS_INLINE
+        triangular_adaptor (const triangular_adaptor &m):
+            matrix_expression<self_type> (),
+            data_ (m.data_) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return data_.size1 ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return data_.size2 ();
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const matrix_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        matrix_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+            if (triangular_type::other (i, j))
+                return data () (i, j);
+            else if (triangular_type::one (i, j))
+                return one_;
+            else
+                return zero_;
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+            if (!triangular_type::other (i, j)) {
+                bad_index ().raise ();
+                // NEVER reached
+            }
+            return data () (i, j);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) const {
+            BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
+            BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
+            if (!triangular_type::other (i, j)) {
+                bad_index ().raise ();
+                // NEVER reached
+            }
+            return data () (i, j);
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        triangular_adaptor &operator = (const triangular_adaptor &m) {
+            matrix_assign<scalar_assign> (*this, m);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        triangular_adaptor &assign_temporary (triangular_adaptor &m) {
+            *this = m;
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_adaptor &operator = (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, matrix<value_type> (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_adaptor &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_adaptor& operator += (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_adaptor &plus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_adaptor& operator -= (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        triangular_adaptor &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        triangular_adaptor& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        triangular_adaptor& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const triangular_adaptor &ta) const {
+            return (*this).data ().same_closure (ta.data ());
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (triangular_adaptor &m) {
+            if (this != &m)
+                matrix_swap<scalar_swap> (*this, m);
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (triangular_adaptor &m1, triangular_adaptor &m2) {
+            m1.swap (m2);
+        }
+
+        // Iterator types
+   private:
+        typedef typename M::const_iterator1 const_subiterator1_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator1,
+                                          typename M::iterator1>::type subiterator1_type;
+        typedef typename M::const_iterator2 const_subiterator2_type;
+        typedef typename boost::mpl::if_<boost::is_const<M>,
+                                          typename M::const_iterator2,
+                                          typename M::iterator2>::type subiterator2_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
+        typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
+        typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
+        typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
+#else
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+#endif
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator1 find1 (int rank, size_type i, size_type j) const {
+            if (rank == 1)
+                i = triangular_type::restrict1 (i, j, size1(), size2());
+            if (rank == 0)
+                i = triangular_type::global_restrict1 (i, size1(), j, size2());
+            return const_iterator1 (*this, data ().find1 (rank, i, j));
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 find1 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                i = triangular_type::mutable_restrict1 (i, j, size1(), size2());
+            if (rank == 0)
+                i = triangular_type::global_mutable_restrict1 (i, size1(), j, size2());
+            return iterator1 (*this, data ().find1 (rank, i, j));
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 find2 (int rank, size_type i, size_type j) const {
+            if (rank == 1)
+                j = triangular_type::restrict2 (i, j, size1(), size2());
+            if (rank == 0)
+                j = triangular_type::global_restrict2 (i, size1(), j, size2());
+            return const_iterator2 (*this, data ().find2 (rank, i, j));
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 find2 (int rank, size_type i, size_type j) {
+            if (rank == 1)
+                j = triangular_type::mutable_restrict2 (i, j, size1(), size2());
+            if (rank == 0)
+                j = triangular_type::global_mutable_restrict2 (i, size1(), j, size2());
+            return iterator2 (*this, data ().find2 (rank, i, j));
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator1:
+            public container_const_reference<triangular_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename const_subiterator1_type::value_type value_type;
+            typedef typename const_subiterator1_type::difference_type difference_type;
+            typedef typename const_subiterator1_type::reference reference;
+            typedef typename const_subiterator1_type::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), it1_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, const const_subiterator1_type &it1):
+                container_const_reference<self_type> (m), it1_ (it1) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), it1_ (it.it1_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                size_type i = index1 ();
+                size_type j = index2 ();
+                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
+                if (triangular_type::other (i, j))
+                    return *it1_;
+                else
+                    return (*this) () (i, j);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it1_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1 (), 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator1:
+            public container_reference<triangular_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               iterator1, value_type> {
+        public:
+            typedef typename subiterator1_type::value_type value_type;
+            typedef typename subiterator1_type::difference_type difference_type;
+            typedef typename subiterator1_type::reference reference;
+            typedef typename subiterator1_type::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), it1_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, const subiterator1_type &it1):
+                container_reference<self_type> (m), it1_ (it1) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                size_type i = index1 ();
+                size_type j = index2 ();
+                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
+                if (triangular_type::other (i, j))
+                    return *it1_;
+                else
+                    return (*this) () (i, j);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                return (*this) ().find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it1_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it1_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            subiterator1_type it1_;
+
+            friend class const_iterator1;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1 (), 0);
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator2:
+            public container_const_reference<triangular_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename const_subiterator2_type::value_type value_type;
+            typedef typename const_subiterator2_type::difference_type difference_type;
+            typedef typename const_subiterator2_type::reference reference;
+            typedef typename const_subiterator2_type::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (m), it2_ (it2) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), it2_ (it.it2_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                size_type i = index1 ();
+                size_type j = index2 ();
+                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
+                if (triangular_type::other (i, j))
+                    return *it2_;
+                else
+                    return (*this) () (i, j);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it2_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator2:
+            public container_reference<triangular_adaptor>,
+            public random_access_iterator_base<typename iterator_restrict_traits<
+                                                   typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
+                                               iterator2, value_type> {
+        public:
+            typedef typename subiterator2_type::value_type value_type;
+            typedef typename subiterator2_type::difference_type difference_type;
+            typedef typename subiterator2_type::reference reference;
+            typedef typename subiterator2_type::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, const subiterator2_type &it2):
+                container_reference<self_type> (m), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                size_type i = index1 ();
+                size_type j = index2 ();
+                BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
+                if (triangular_type::other (i, j))
+                    return *it2_;
+                else
+                    return (*this) () (i, j);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                return (*this) ().find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                return it2_.index1 ();
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                return it2_.index2 ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            subiterator2_type it2_;
+
+            friend class const_iterator2;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2 ());
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+    private:
+        matrix_closure_type data_;
+        static const value_type zero_;
+        static const value_type one_;
+    };
+
+    template<class M, class TRI>
+    const typename triangular_adaptor<M, TRI>::value_type triangular_adaptor<M, TRI>::zero_ = value_type/*zero*/();
+    template<class M, class TRI>
+    const typename triangular_adaptor<M, TRI>::value_type triangular_adaptor<M, TRI>::one_ (1);
+
+    template <class M, class TRI>
+    struct vector_temporary_traits< triangular_adaptor<M, TRI> >
+    : vector_temporary_traits< typename boost::remove_const<M>::type > {} ;
+    template <class M, class TRI>
+    struct vector_temporary_traits< const triangular_adaptor<M, TRI> >
+    : vector_temporary_traits< typename boost::remove_const<M>::type > {} ;
+
+    template <class M, class TRI>
+    struct matrix_temporary_traits< triangular_adaptor<M, TRI> >
+    : matrix_temporary_traits< typename boost::remove_const<M>::type > {};
+    template <class M, class TRI>
+    struct matrix_temporary_traits< const triangular_adaptor<M, TRI> >
+    : matrix_temporary_traits< typename boost::remove_const<M>::type > {};
+
+
+    template<class E1, class E2>
+    struct matrix_vector_solve_traits {
+        typedef typename promote_traits<typename E1::value_type, typename E2::value_type>::promote_type promote_type;
+        typedef vector<promote_type> result_type;
+    };
+
+    // Operations:
+    //  n * (n - 1) / 2 + n = n * (n + 1) / 2 multiplications,
+    //  n * (n - 1) / 2 additions
+
+    // Dense (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        lower_tag, column_major_tag, dense_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e2 ().size ();
+        for (size_type n = 0; n < size; ++ n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n) /= e1 () (n, n);
+            if (t != value_type/*zero*/()) {
+                for (size_type m = n + 1; m < size; ++ m)
+                    e2 () (m) -= e1 () (m, n) * t;
+            }
+        }
+    }
+    // Packed (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        lower_tag, column_major_tag, packed_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e2 ().size ();
+        for (size_type n = 0; n < size; ++ n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n) /= e1 () (n, n);
+            if (t != value_type/*zero*/()) {
+                typename E1::const_iterator1 it1e1 (e1 ().find1 (1, n + 1, n));
+                typename E1::const_iterator1 it1e1_end (e1 ().find1 (1, e1 ().size1 (), n));
+                difference_type m (it1e1_end - it1e1);
+                while (-- m >= 0)
+                    e2 () (it1e1.index1 ()) -= *it1e1 * t, ++ it1e1;
+            }
+        }
+    }
+    // Sparse (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        lower_tag, column_major_tag, unknown_storage_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e2 ().size ();
+        for (size_type n = 0; n < size; ++ n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n) /= e1 () (n, n);
+            if (t != value_type/*zero*/()) {
+                typename E1::const_iterator1 it1e1 (e1 ().find1 (1, n + 1, n));
+                typename E1::const_iterator1 it1e1_end (e1 ().find1 (1, e1 ().size1 (), n));
+                while (it1e1 != it1e1_end)
+                    e2 () (it1e1.index1 ()) -= *it1e1 * t, ++ it1e1;
+            }
+        }
+    }
+
+    // Dense (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        lower_tag, row_major_tag, dense_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e2 ().size ();
+        for (size_type n = 0; n < size; ++ n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n) /= e1 () (n, n);
+            if (t != value_type/*zero*/()) {
+                for (size_type m = n + 1; m < size; ++ m)
+                    e2 () (m) -= e1 () (m, n) * t;
+            }
+        }
+    }
+    // Packed (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        lower_tag, row_major_tag, packed_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e2 ().size ();
+        for (size_type n = 0; n < size; ++ n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n);
+            typename E1::const_iterator2 it2e1 (e1 ().find2 (1, n, 0));
+            typename E1::const_iterator2 it2e1_end (e1 ().find2 (1, n, n));
+            while (it2e1 != it2e1_end) {
+              t -= *it2e1 * e2 () (it2e1.index2());
+              ++ it2e1;
+            }
+            e2() (n) = t / e1 () (n, n);
+        }
+    }
+    // Sparse (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        lower_tag, row_major_tag, unknown_storage_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e2 ().size ();
+        for (size_type n = 0; n < size; ++ n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n);
+            typename E1::const_iterator2 it2e1 (e1 ().find2 (1, n, 0));
+            typename E1::const_iterator2 it2e1_end (e1 ().find2 (1, n, n));
+            while (it2e1 != it2e1_end) {
+              t -= *it2e1 * e2 () (it2e1.index2());
+              ++ it2e1;
+            }
+            e2() (n) = t / e1 () (n, n);
+        }
+    }
+
+    // Redirectors :-)
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        lower_tag, column_major_tag) {
+        typedef typename E1::storage_category storage_category;
+        inplace_solve (e1, e2,
+                       lower_tag (), column_major_tag (), storage_category ());
+    }
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        lower_tag, row_major_tag) {
+        typedef typename E1::storage_category storage_category;
+        inplace_solve (e1, e2,
+                       lower_tag (), row_major_tag (), storage_category ());
+    }
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        lower_tag) {
+        typedef typename E1::orientation_category orientation_category;
+        inplace_solve (e1, e2,
+                       lower_tag (), orientation_category ());
+    }
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        unit_lower_tag) {
+        typedef typename E1::orientation_category orientation_category;
+        inplace_solve (triangular_adaptor<const E1, unit_lower> (e1 ()), e2,
+                       unit_lower_tag (), orientation_category ());
+    }
+
+    // Dense (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        upper_tag, column_major_tag, dense_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e2 ().size ();
+        for (difference_type n = size - 1; n >= 0; -- n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n) /= e1 () (n, n);
+            if (t != value_type/*zero*/()) {
+                for (difference_type m = n - 1; m >= 0; -- m)
+                    e2 () (m) -= e1 () (m, n) * t;
+            }
+        }
+    }
+    // Packed (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        upper_tag, column_major_tag, packed_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e2 ().size ();
+        for (difference_type n = size - 1; n >= 0; -- n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n) /= e1 () (n, n);
+            if (t != value_type/*zero*/()) {
+                typename E1::const_reverse_iterator1 it1e1 (e1 ().find1 (1, n, n));
+                typename E1::const_reverse_iterator1 it1e1_rend (e1 ().find1 (1, 0, n));
+                while (it1e1 != it1e1_rend) {
+                  e2 () (it1e1.index1 ()) -= *it1e1 * t, ++ it1e1;
+                }
+            }
+        }
+    }
+    // Sparse (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        upper_tag, column_major_tag, unknown_storage_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e2 ().size ();
+        for (difference_type n = size - 1; n >= 0; -- n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n) /= e1 () (n, n);
+            if (t != value_type/*zero*/()) {
+                typename E1::const_reverse_iterator1 it1e1 (e1 ().find1 (1, n, n));
+                typename E1::const_reverse_iterator1 it1e1_rend (e1 ().find1 (1, 0, n));
+                while (it1e1 != it1e1_rend) {
+                  e2 () (it1e1.index1 ()) -= *it1e1 * t, ++ it1e1;
+                }
+            }
+        }
+    }
+
+    // Dense (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        upper_tag, row_major_tag, dense_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e1 ().size1 ();
+        for (difference_type n = size-1; n >=0; -- n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n);
+            for (difference_type m = n + 1; m < static_cast<difference_type>(e1 ().size2()); ++ m) {
+              t -= e1 () (n, m)  * e2 () (m);
+            }
+            e2() (n) = t / e1 () (n, n);
+        }
+    }
+    // Packed (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        upper_tag, row_major_tag, packed_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e1 ().size1 ();
+        for (difference_type n = size-1; n >=0; -- n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n);
+            typename E1::const_iterator2 it2e1 (e1 ().find2 (1, n, n+1));
+            typename E1::const_iterator2 it2e1_end (e1 ().find2 (1, n, e1 ().size2 ()));
+            while (it2e1 != it2e1_end) {
+              t -= *it2e1 * e2 () (it2e1.index2());
+              ++ it2e1;
+            }
+            e2() (n) = t / e1 () (n, n);
+
+        }
+    }
+    // Sparse (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        upper_tag, row_major_tag, unknown_storage_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size (), bad_size ());
+        size_type size = e1 ().size1 ();
+        for (difference_type n = size-1; n >=0; -- n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            value_type t = e2 () (n);
+            typename E1::const_iterator2 it2e1 (e1 ().find2 (1, n, n+1));
+            typename E1::const_iterator2 it2e1_end (e1 ().find2 (1, n, e1 ().size2 ()));
+            while (it2e1 != it2e1_end) {
+              t -= *it2e1 * e2 () (it2e1.index2());
+              ++ it2e1;
+            }
+            e2() (n) = t / e1 () (n, n);
+
+        }
+    }
+
+    // Redirectors :-)
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        upper_tag, column_major_tag) {
+        typedef typename E1::storage_category storage_category;
+        inplace_solve (e1, e2,
+                       upper_tag (), column_major_tag (), storage_category ());
+    }
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        upper_tag, row_major_tag) {
+        typedef typename E1::storage_category storage_category;
+        inplace_solve (e1, e2,
+                       upper_tag (), row_major_tag (), storage_category ());
+    }
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        upper_tag) {
+        typedef typename E1::orientation_category orientation_category;
+        inplace_solve (e1, e2,
+                       upper_tag (), orientation_category ());
+    }
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, vector_expression<E2> &e2,
+                        unit_upper_tag) {
+        typedef typename E1::orientation_category orientation_category;
+        inplace_solve (triangular_adaptor<const E1, unit_upper> (e1 ()), e2,
+                       unit_upper_tag (), orientation_category ());
+    }
+
+    template<class E1, class E2, class C>
+    BOOST_UBLAS_INLINE
+    typename matrix_vector_solve_traits<E1, E2>::result_type
+    solve (const matrix_expression<E1> &e1,
+           const vector_expression<E2> &e2,
+           C) {
+        typename matrix_vector_solve_traits<E1, E2>::result_type r (e2);
+        inplace_solve (e1, r, C ());
+        return r;
+    }
+
+
+    // Redirectors :-)
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (vector_expression<E1> &e1, const matrix_expression<E2> &e2,
+                        lower_tag, row_major_tag) {
+        typedef typename E2::storage_category storage_category;
+        inplace_solve (trans(e2), e1,
+                       upper_tag (), column_major_tag (), storage_category ());
+    }
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (vector_expression<E1> &e1, const matrix_expression<E2> &e2,
+                        lower_tag, column_major_tag) {
+        typedef typename E2::storage_category storage_category;
+        inplace_solve (trans (e2), e1,
+                       upper_tag (), row_major_tag (), storage_category ());
+    }
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (vector_expression<E1> &e1, const matrix_expression<E2> &e2,
+                        lower_tag) {
+        typedef typename E2::orientation_category orientation_category;
+        inplace_solve (e1, e2,
+                       lower_tag (), orientation_category ());
+    }
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (vector_expression<E1> &e1, const matrix_expression<E2> &e2,
+                        unit_lower_tag) {
+        typedef typename E2::orientation_category orientation_category;
+        inplace_solve (e1, triangular_adaptor<const E2, unit_lower> (e2 ()),
+                       unit_lower_tag (), orientation_category ());
+    }
+
+
+    // Redirectors :-)
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (vector_expression<E1> &e1, const matrix_expression<E2> &e2,
+                        upper_tag, row_major_tag) {
+        typedef typename E2::storage_category storage_category;
+        inplace_solve (trans(e2), e1,
+                       lower_tag (), column_major_tag (), storage_category ());
+    }
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (vector_expression<E1> &e1, const matrix_expression<E2> &e2,
+                        upper_tag, column_major_tag) {
+        typedef typename E2::storage_category storage_category;
+        inplace_solve (trans (e2), e1,
+                       lower_tag (), row_major_tag (), storage_category ());
+    }
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (vector_expression<E1> &e1, const matrix_expression<E2> &e2,
+                        upper_tag) {
+        typedef typename E2::orientation_category orientation_category;
+        inplace_solve (e1, e2,
+                       upper_tag (), orientation_category ());
+    }
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (vector_expression<E1> &e1, const matrix_expression<E2> &e2,
+                        unit_upper_tag) {
+        typedef typename E2::orientation_category orientation_category;
+        inplace_solve (e1, triangular_adaptor<const E2, unit_upper> (e2 ()),
+                       unit_upper_tag (), orientation_category ());
+    }
+
+    template<class E1, class E2, class C>
+    BOOST_UBLAS_INLINE
+    typename matrix_vector_solve_traits<E1, E2>::result_type
+    solve (const vector_expression<E1> &e1,
+           const matrix_expression<E2> &e2,
+           C) {
+        typename matrix_vector_solve_traits<E1, E2>::result_type r (e1);
+        inplace_solve (r, e2, C ());
+        return r;
+    }
+
+    template<class E1, class E2>
+    struct matrix_matrix_solve_traits {
+        typedef typename promote_traits<typename E1::value_type, typename E2::value_type>::promote_type promote_type;
+        typedef matrix<promote_type> result_type;
+    };
+
+    // Operations:
+    //  k * n * (n - 1) / 2 + k * n = k * n * (n + 1) / 2 multiplications,
+    //  k * n * (n - 1) / 2 additions
+
+    // Dense (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, matrix_expression<E2> &e2,
+                        lower_tag, dense_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size1 (), bad_size ());
+        size_type size1 = e2 ().size1 ();
+        size_type size2 = e2 ().size2 ();
+        for (size_type n = 0; n < size1; ++ n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            for (size_type l = 0; l < size2; ++ l) {
+                value_type t = e2 () (n, l) /= e1 () (n, n);
+                if (t != value_type/*zero*/()) {
+                    for (size_type m = n + 1; m < size1; ++ m)
+                        e2 () (m, l) -= e1 () (m, n) * t;
+                }
+            }
+        }
+    }
+    // Packed (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, matrix_expression<E2> &e2,
+                        lower_tag, packed_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size1 (), bad_size ());
+        size_type size1 = e2 ().size1 ();
+        size_type size2 = e2 ().size2 ();
+        for (size_type n = 0; n < size1; ++ n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            for (size_type l = 0; l < size2; ++ l) {
+                value_type t = e2 () (n, l) /= e1 () (n, n);
+                if (t != value_type/*zero*/()) {
+                    typename E1::const_iterator1 it1e1 (e1 ().find1 (1, n + 1, n));
+                    typename E1::const_iterator1 it1e1_end (e1 ().find1 (1, e1 ().size1 (), n));
+                    difference_type m (it1e1_end - it1e1);
+                    while (-- m >= 0)
+                        e2 () (it1e1.index1 (), l) -= *it1e1 * t, ++ it1e1;
+                }
+            }
+        }
+    }
+    // Sparse (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, matrix_expression<E2> &e2,
+                        lower_tag, unknown_storage_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size1 (), bad_size ());
+        size_type size1 = e2 ().size1 ();
+        size_type size2 = e2 ().size2 ();
+        for (size_type n = 0; n < size1; ++ n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            for (size_type l = 0; l < size2; ++ l) {
+                value_type t = e2 () (n, l) /= e1 () (n, n);
+                if (t != value_type/*zero*/()) {
+                    typename E1::const_iterator1 it1e1 (e1 ().find1 (1, n + 1, n));
+                    typename E1::const_iterator1 it1e1_end (e1 ().find1 (1, e1 ().size1 (), n));
+                    while (it1e1 != it1e1_end)
+                        e2 () (it1e1.index1 (), l) -= *it1e1 * t, ++ it1e1;
+                }
+            }
+        }
+    }
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, matrix_expression<E2> &e2,
+                        lower_tag) {
+        typedef typename E1::storage_category dispatch_category;
+        inplace_solve (e1, e2,
+                       lower_tag (), dispatch_category ());
+    }
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, matrix_expression<E2> &e2,
+                        unit_lower_tag) {
+        typedef typename E1::storage_category dispatch_category;
+        inplace_solve (triangular_adaptor<const E1, unit_lower> (e1 ()), e2,
+                       unit_lower_tag (), dispatch_category ());
+    }
+
+    // Dense (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, matrix_expression<E2> &e2,
+                        upper_tag, dense_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size1 (), bad_size ());
+        size_type size1 = e2 ().size1 ();
+        size_type size2 = e2 ().size2 ();
+        for (difference_type n = size1 - 1; n >= 0; -- n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            for (difference_type l = size2 - 1; l >= 0; -- l) {
+                value_type t = e2 () (n, l) /= e1 () (n, n);
+                if (t != value_type/*zero*/()) {
+                    for (difference_type m = n - 1; m >= 0; -- m)
+                        e2 () (m, l) -= e1 () (m, n) * t;
+                }
+            }
+        }
+    }
+    // Packed (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, matrix_expression<E2> &e2,
+                        upper_tag, packed_proxy_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size1 (), bad_size ());
+        size_type size1 = e2 ().size1 ();
+        size_type size2 = e2 ().size2 ();
+        for (difference_type n = size1 - 1; n >= 0; -- n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            for (difference_type l = size2 - 1; l >= 0; -- l) {
+                value_type t = e2 () (n, l) /= e1 () (n, n);
+                if (t != value_type/*zero*/()) {
+                    typename E1::const_reverse_iterator1 it1e1 (e1 ().find1 (1, n, n));
+                    typename E1::const_reverse_iterator1 it1e1_rend (e1 ().find1 (1, 0, n));
+                    difference_type m (it1e1_rend - it1e1);
+                    while (-- m >= 0)
+                        e2 () (it1e1.index1 (), l) -= *it1e1 * t, ++ it1e1;
+                }
+            }
+        }
+    }
+    // Sparse (proxy) case
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, matrix_expression<E2> &e2,
+                        upper_tag, unknown_storage_tag) {
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename E2::value_type value_type;
+
+        BOOST_UBLAS_CHECK (e1 ().size1 () == e1 ().size2 (), bad_size ());
+        BOOST_UBLAS_CHECK (e1 ().size2 () == e2 ().size1 (), bad_size ());
+        size_type size1 = e2 ().size1 ();
+        size_type size2 = e2 ().size2 ();
+        for (difference_type n = size1 - 1; n >= 0; -- n) {
+#ifndef BOOST_UBLAS_SINGULAR_CHECK
+            BOOST_UBLAS_CHECK (e1 () (n, n) != value_type/*zero*/(), singular ());
+#else
+            if (e1 () (n, n) == value_type/*zero*/())
+                singular ().raise ();
+#endif
+            for (difference_type l = size2 - 1; l >= 0; -- l) {
+                value_type t = e2 () (n, l) /= e1 () (n, n);
+                if (t != value_type/*zero*/()) {
+                    typename E1::const_reverse_iterator1 it1e1 (e1 ().find1 (1, n, n));
+                    typename E1::const_reverse_iterator1 it1e1_rend (e1 ().find1 (1, 0, n));
+                    while (it1e1 != it1e1_rend)
+                        e2 () (it1e1.index1 (), l) -= *it1e1 * t, ++ it1e1;
+                }
+            }
+        }
+    }
+    // Dispatcher
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, matrix_expression<E2> &e2,
+                        upper_tag) {
+        typedef typename E1::storage_category dispatch_category;
+        inplace_solve (e1, e2,
+                       upper_tag (), dispatch_category ());
+    }
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    void inplace_solve (const matrix_expression<E1> &e1, matrix_expression<E2> &e2,
+                        unit_upper_tag) {
+        typedef typename E1::storage_category dispatch_category;
+        inplace_solve (triangular_adaptor<const E1, unit_upper> (e1 ()), e2,
+                       unit_upper_tag (), dispatch_category ());
+    }
+
+    template<class E1, class E2, class C>
+    BOOST_UBLAS_INLINE
+    typename matrix_matrix_solve_traits<E1, E2>::result_type
+    solve (const matrix_expression<E1> &e1,
+           const matrix_expression<E2> &e2,
+           C) {
+        typename matrix_matrix_solve_traits<E1, E2>::result_type r (e2);
+        inplace_solve (e1, r, C ());
+        return r;
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/vector.hpp b/include/boost/numeric/ublas/vector.hpp
new file mode 100644
index 0000000..c1384c1
--- /dev/null
+++ b/include/boost/numeric/ublas/vector.hpp
@@ -0,0 +1,2954 @@
+//
+//  Copyright (c) 2000-2010
+//  Joerg Walter, Mathias Koch, David Bellot
+//  Copyright (c) 2014, Athanasios Iliopoulos
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+//  And we acknowledge the support from all contributors.
+
+/// \file vector.hpp Definition for the class vector and its derivative
+
+#ifndef _BOOST_UBLAS_VECTOR_
+#define _BOOST_UBLAS_VECTOR_
+
+#include <boost/config.hpp>
+#include <boost/numeric/ublas/storage.hpp>
+#include <boost/numeric/ublas/vector_expression.hpp>
+#include <boost/numeric/ublas/detail/vector_assign.hpp>
+#include <boost/serialization/collection_size_type.hpp>
+#include <boost/serialization/nvp.hpp>
+
+#ifdef BOOST_UBLAS_CPP_GE_2011
+#include <array>
+#include <initializer_list>
+#if defined(BOOST_MSVC) // For std::forward in fixed_vector
+#include <utility>
+#endif
+#endif
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+
+	 /** \brief A dense vector of values of type \c T.
+	  *
+	  * For a \f$n\f$-dimensional vector \f$v\f$ and \f$0\leq i < n\f$ every element \f$v_i\f$ is mapped 
+	  * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c unbounded_array. 
+	  * Elements are constructed by \c A, which need not initialise their value.
+	  *
+	  * \tparam T type of the objects stored in the vector (like int, double, complex,...)
+	  * \tparam A The type of the storage array of the vector. Default is \c unbounded_array<T>. \c <bounded_array<T> and \c std::vector<T> can also be used
+	  */
+	 template<class T, class A>
+	 class vector:
+	     public vector_container<vector<T, A> > {
+
+	     typedef vector<T, A> self_type;
+	 public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+	     using vector_container<self_type>::operator ();
+#endif
+
+	typedef typename A::size_type size_type;
+	    typedef typename A::difference_type difference_type;
+	    typedef T value_type;
+	    typedef typename type_traits<T>::const_reference const_reference;
+	    typedef T &reference;
+	    typedef T *pointer;
+	    typedef const T *const_pointer;
+	    typedef A array_type;
+	    typedef const vector_reference<const self_type> const_closure_type;
+	    typedef vector_reference<self_type> closure_type;
+	    typedef self_type vector_temporary_type;
+	    typedef dense_tag storage_category;
+
+	    // Construction and destruction
+	
+	/// \brief Constructor of a vector
+	/// By default it is empty, i.e. \c size()==0.
+	    BOOST_UBLAS_INLINE
+	    vector ():
+	        vector_container<self_type> (),
+	        data_ () {}
+
+	/// \brief Constructor of a vector with a predefined size
+	/// By default, its elements are initialized to 0.
+	/// \param size initial size of the vector
+	    explicit BOOST_UBLAS_INLINE
+	    vector (size_type size):
+	        vector_container<self_type> (),
+	        data_ (size) {
+	    }
+
+	/// \brief Constructor of a vector by copying from another container
+	/// This type has the generic name \c array_typ within the vector definition.
+	/// \param size initial size of the vector \bug this value is not used
+	/// \param data container of type \c A
+	/// \todo remove this definition because \c size is not used
+	    BOOST_UBLAS_INLINE
+        vector (size_type /*size*/, const array_type &data):
+	        vector_container<self_type> (),
+	        data_ (data) {}
+
+	/// \brief Constructor of a vector by copying from another container
+	/// This type has the generic name \c array_typ within the vector definition.
+	/// \param data container of type \c A
+	     BOOST_UBLAS_INLINE
+	     vector (const array_type &data):
+	         vector_container<self_type> (),
+	         data_ (data) {}
+
+	/// \brief Constructor of a vector with a predefined size and a unique initial value
+	/// \param size of the vector
+	/// \param init value to assign to each element of the vector
+	    BOOST_UBLAS_INLINE
+	    vector (size_type size, const value_type &init):
+	        vector_container<self_type> (),
+	        data_ (size, init) {}
+
+	/// \brief Copy-constructor of a vector
+	/// \param v is the vector to be duplicated
+	    BOOST_UBLAS_INLINE
+	    vector (const vector &v):
+	        vector_container<self_type> (),
+	        data_ (v.data_) {}
+
+	/// \brief Copy-constructor of a vector from a vector_expression
+	/// Depending on the vector_expression, this constructor can have the cost of the computations 
+	/// of the expression (trivial to say it, but it is to take into account in your complexity calculations).
+	/// \param ae the vector_expression which values will be duplicated into the vector
+	    template<class AE>
+	    BOOST_UBLAS_INLINE
+	    vector (const vector_expression<AE> &ae):
+	        vector_container<self_type> (),
+	        data_ (ae ().size ()) {
+	        vector_assign<scalar_assign> (*this, ae);
+	    }
+
+	// -----------------------
+	// Random Access Container
+	// -----------------------
+	
+	/// \brief Return the maximum size of the data container.
+	/// Return the upper bound (maximum size) on the data container. Depending on the container, it can be bigger than the current size of the vector.
+	    BOOST_UBLAS_INLINE
+	    size_type max_size () const {
+	        return data_.max_size ();
+	    }
+	    
+	/// \brief Return true if the vector is empty (\c size==0)
+	/// \return \c true if empty, \c false otherwise
+	    BOOST_UBLAS_INLINE
+	    bool empty () const {
+	        return data_.size () == 0;
+	    }
+
+	// ---------
+	// Accessors
+	// ---------
+	
+	/// \brief Return the size of the vector
+	     BOOST_UBLAS_INLINE
+	     size_type size () const {
+	         return data_.size ();
+	     }
+
+	// -----------------
+	// Storage accessors
+	// -----------------
+	
+	/// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
+	     BOOST_UBLAS_INLINE
+	     const array_type &data () const {
+	         return data_;
+	     }
+
+	/// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
+	     BOOST_UBLAS_INLINE
+	     array_type &data () {
+	         return data_;
+	     }
+
+	// --------
+	     // Resizing
+	// --------
+	
+	/// \brief Resize the vector
+	/// Resize the vector to a new size. If \c preserve is true, data are copied otherwise data are lost. If the new size is bigger, the remaining values are filled in with the initial value (0 by default) in the case of \c unbounded_array, which is the container by default. If the new size is smaller, last values are lost. This behaviour can be different if you explicitely specify another type of container.
+	/// \param size new size of the vector
+	/// \param preserve if true, keep values
+	     BOOST_UBLAS_INLINE
+	     void resize (size_type size, bool preserve = true) {
+	         if (preserve)
+	             data ().resize (size, typename A::value_type ());
+	         else
+	             data ().resize (size);
+	     }
+
+	// ---------------
+	     // Element support
+	// ---------------
+	
+	/// \brief Return a pointer to the element \f$i\f$
+	/// \param i index of the element
+	// XXX this semantic is not the one expected by the name of this method
+	     BOOST_UBLAS_INLINE
+	     pointer find_element (size_type i) {
+	         return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
+	     }
+
+	/// \brief Return a const pointer to the element \f$i\f$
+	/// \param i index of the element
+	// XXX  this semantic is not the one expected by the name of this method
+	     BOOST_UBLAS_INLINE
+	     const_pointer find_element (size_type i) const {
+	         return & (data () [i]);
+	     }
+
+	// --------------
+	     // Element access
+	// --------------
+
+	/// \brief Return a const reference to the element \f$i\f$
+	/// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
+	/// \param i index of the element
+	     BOOST_UBLAS_INLINE
+	     const_reference operator () (size_type i) const {
+	         return data () [i];
+	     }
+	
+	/// \brief Return a reference to the element \f$i\f$
+	/// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
+	/// \param i index of the element
+	     BOOST_UBLAS_INLINE
+	     reference operator () (size_type i) {
+	         return data () [i];
+	     }
+
+	/// \brief Return a const reference to the element \f$i\f$
+	/// \param i index of the element
+	     BOOST_UBLAS_INLINE
+	     const_reference operator [] (size_type i) const {
+	         return (*this) (i);
+	     }
+	
+	/// \brief Return a reference to the element \f$i\f$
+	/// \param i index of the element
+	     BOOST_UBLAS_INLINE
+	     reference operator [] (size_type i) {
+	         return (*this) (i);
+	     }
+
+	// ------------------
+	     // Element assignment
+	// ------------------
+	
+	/// \brief Set element \f$i\f$ to the value \c t
+	/// \param i index of the element
+	/// \param t reference to the value to be set
+	// XXX semantic of this is to insert a new element and therefore size=size+1 ?
+	     BOOST_UBLAS_INLINE
+	     reference insert_element (size_type i, const_reference t) {
+	         return (data () [i] = t);
+	     }
+
+	/// \brief Set element \f$i\f$ to the \e zero value
+	/// \param i index of the element
+	     BOOST_UBLAS_INLINE
+	     void erase_element (size_type i) {
+	         data () [i] = value_type/*zero*/();
+	     }
+	     
+	// -------
+	     // Zeroing
+	// -------
+	
+	/// \brief Clear the vector, i.e. set all values to the \c zero value.
+	     BOOST_UBLAS_INLINE
+	     void clear () {
+	         std::fill (data ().begin (), data ().end (), value_type/*zero*/());
+	     }
+
+	     // Assignment
+#ifdef BOOST_UBLAS_MOVE_SEMANTICS
+
+	/// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
+	/// \param v is the source vector
+	/// \return a reference to a vector (i.e. the destination vector)
+	     /*! @note "pass by value" the key idea to enable move semantics */
+	     BOOST_UBLAS_INLINE
+	     vector &operator = (vector v) {
+	         assign_temporary(v);
+	         return *this;
+	     }
+#else
+	/// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
+	/// \param v is the source vector
+	/// \return a reference to a vector (i.e. the destination vector)
+	     BOOST_UBLAS_INLINE
+	     vector &operator = (const vector &v) {
+	         data () = v.data ();
+	         return *this;
+	     }
+#endif
+
+	/// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
+	/// Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector). This method does not create any temporary.
+	/// \param v is the source vector container
+	/// \return a reference to a vector (i.e. the destination vector)
+	     template<class C>          // Container assignment without temporary
+	     BOOST_UBLAS_INLINE
+	     vector &operator = (const vector_container<C> &v) {
+	         resize (v ().size (), false);
+	         assign (v);
+	         return *this;
+	     }
+
+	/// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
+	/// \param v is the source vector
+	/// \return a reference to a vector (i.e. the destination vector)
+	     BOOST_UBLAS_INLINE
+	     vector &assign_temporary (vector &v) {
+	         swap (v);
+	         return *this;
+	     }
+
+	/// \brief Assign the result of a vector_expression to the vector
+	/// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+	/// \tparam AE is the type of the vector_expression
+	/// \param ae is a const reference to the vector_expression
+	/// \return a reference to the resulting vector
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     vector &operator = (const vector_expression<AE> &ae) {
+	         self_type temporary (ae);
+	         return assign_temporary (temporary);
+	     }
+
+	/// \brief Assign the result of a vector_expression to the vector
+	/// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+	/// \tparam AE is the type of the vector_expression
+	/// \param ae is a const reference to the vector_expression
+	/// \return a reference to the resulting vector
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     vector &assign (const vector_expression<AE> &ae) {
+	         vector_assign<scalar_assign> (*this, ae);
+	         return *this;
+	     }
+
+	// -------------------
+	     // Computed assignment
+	// -------------------
+	
+	/// \brief Assign the sum of the vector and a vector_expression to the vector
+	/// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+	/// A temporary is created for the computations.
+	/// \tparam AE is the type of the vector_expression
+	/// \param ae is a const reference to the vector_expression
+	/// \return a reference to the resulting vector
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     vector &operator += (const vector_expression<AE> &ae) {
+	         self_type temporary (*this + ae);
+	         return assign_temporary (temporary);
+	     }
+
+	/// \brief Assign the sum of the vector and a vector_expression to the vector
+	/// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+	/// No temporary is created. Computations are done and stored directly into the resulting vector.
+	/// \tparam AE is the type of the vector_expression
+	/// \param ae is a const reference to the vector_expression
+	/// \return a reference to the resulting vector
+	     template<class C>          // Container assignment without temporary
+	     BOOST_UBLAS_INLINE
+	     vector &operator += (const vector_container<C> &v) {
+	         plus_assign (v);
+	         return *this;
+	     }
+
+	/// \brief Assign the sum of the vector and a vector_expression to the vector
+	/// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+	/// No temporary is created. Computations are done and stored directly into the resulting vector.
+	/// \tparam AE is the type of the vector_expression
+	/// \param ae is a const reference to the vector_expression
+	/// \return a reference to the resulting vector
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     vector &plus_assign (const vector_expression<AE> &ae) {
+	         vector_assign<scalar_plus_assign> (*this, ae);
+	         return *this;
+	     }
+	
+	/// \brief Assign the difference of the vector and a vector_expression to the vector
+	/// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+	/// A temporary is created for the computations.
+	/// \tparam AE is the type of the vector_expression
+	/// \param ae is a const reference to the vector_expression
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     vector &operator -= (const vector_expression<AE> &ae) {
+	         self_type temporary (*this - ae);
+	         return assign_temporary (temporary);
+	     }
+
+	/// \brief Assign the difference of the vector and a vector_expression to the vector
+	/// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+	/// No temporary is created. Computations are done and stored directly into the resulting vector.
+	/// \tparam AE is the type of the vector_expression
+	/// \param ae is a const reference to the vector_expression
+	/// \return a reference to the resulting vector
+	     template<class C>          // Container assignment without temporary
+	     BOOST_UBLAS_INLINE
+	     vector &operator -= (const vector_container<C> &v) {
+	         minus_assign (v);
+	         return *this;
+	     }
+
+	/// \brief Assign the difference of the vector and a vector_expression to the vector
+	/// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+	/// No temporary is created. Computations are done and stored directly into the resulting vector.
+	/// \tparam AE is the type of the vector_expression
+	/// \param ae is a const reference to the vector_expression
+	/// \return a reference to the resulting vector
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     vector &minus_assign (const vector_expression<AE> &ae) {
+	         vector_assign<scalar_minus_assign> (*this, ae);
+	         return *this;
+	     }
+
+	/// \brief Assign the product of the vector and a scalar to the vector
+	/// Assign the product of the vector and a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+	/// No temporary is created. Computations are done and stored directly into the resulting vector.
+	/// \tparam AE is the type of the vector_expression
+	/// \param at is a const reference to the scalar
+	/// \return a reference to the resulting vector
+	     template<class AT>
+	     BOOST_UBLAS_INLINE
+	     vector &operator *= (const AT &at) {
+	         vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+	         return *this;
+	     }
+
+	/// \brief Assign the division of the vector by a scalar to the vector
+	/// Assign the division of the vector by a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+	/// No temporary is created. Computations are done and stored directly into the resulting vector.
+	/// \tparam AE is the type of the vector_expression
+	/// \param at is a const reference to the scalar
+	/// \return a reference to the resulting vector
+	    template<class AT>
+	    BOOST_UBLAS_INLINE
+	    vector &operator /= (const AT &at) {
+	        vector_assign_scalar<scalar_divides_assign> (*this, at);
+	        return *this;
+	    }
+	
+	// --------
+	    // Swapping
+	// --------
+	
+	/// \brief Swap the content of the vector with another vector
+	/// \param v is the vector to be swapped with
+	    BOOST_UBLAS_INLINE
+	    void swap (vector &v) {
+	        if (this != &v) {
+	            data ().swap (v.data ());
+	        }
+	    }
+
+	/// \brief Swap the content of two vectors
+	/// \param v1 is the first vector. It takes values from v2
+	/// \param v2 is the second vector It takes values from v1
+	     BOOST_UBLAS_INLINE
+	     friend void swap (vector &v1, vector &v2) {
+	         v1.swap (v2);
+	     }
+
+	     // Iterator types
+	 private:
+	     // Use the storage array iterator
+	     typedef typename A::const_iterator const_subiterator_type;
+	     typedef typename A::iterator subiterator_type;
+
+	 public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	     typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
+	     typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
+#else
+	     class const_iterator;
+	     class iterator;
+#endif
+
+	// --------------
+	    // Element lookup
+	// --------------
+	
+	/// \brief Return a const iterator to the element \e i
+	/// \param i index of the element
+	     BOOST_UBLAS_INLINE
+	     const_iterator find (size_type i) const {
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	         return const_iterator (*this, data ().begin () + i);
+#else
+	         return const_iterator (*this, i);
+#endif
+	     }
+
+	/// \brief Return an iterator to the element \e i
+	/// \param i index of the element
+	     BOOST_UBLAS_INLINE
+	     iterator find (size_type i) {
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	         return iterator (*this, data ().begin () + i);
+#else
+	         return iterator (*this, i);
+#endif
+	     }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	     class const_iterator:
+	         public container_const_reference<vector>,
+	         public random_access_iterator_base<dense_random_access_iterator_tag,
+                   const_iterator, value_type, difference_type> {
+	     public:
+	         typedef typename vector::difference_type difference_type;
+	         typedef typename vector::value_type value_type;
+	         typedef typename vector::const_reference reference;
+	         typedef const typename vector::pointer pointer;
+
+	    // ----------------------------
+	        // Construction and destruction
+	    // ----------------------------
+	
+	
+	        BOOST_UBLAS_INLINE
+	        const_iterator ():
+	            container_const_reference<self_type> (), it_ () {}
+	        BOOST_UBLAS_INLINE
+	        const_iterator (const self_type &v, const const_subiterator_type &it):
+	            container_const_reference<self_type> (v), it_ (it) {}
+	        BOOST_UBLAS_INLINE
+	        const_iterator (const typename self_type::iterator &it):  // ISSUE vector:: stops VC8 using std::iterator here
+	            container_const_reference<self_type> (it ()), it_ (it.it_) {}
+	
+	    // ----------
+	        // Arithmetic
+	    // ----------
+	
+	    /// \brief Increment by 1 the position of the iterator
+	    /// \return a reference to the const iterator
+	        BOOST_UBLAS_INLINE
+	        const_iterator &operator ++ () {
+	            ++ it_;
+	            return *this;
+	        }
+
+	    /// \brief Decrement by 1 the position of the iterator
+	    /// \return a reference to the const iterator
+	        BOOST_UBLAS_INLINE
+	        const_iterator &operator -- () {
+	            -- it_;
+	            return *this;
+	        }
+	  
+	    /// \brief Increment by \e n the position of the iterator 
+	    /// \return a reference to the const iterator
+	        BOOST_UBLAS_INLINE
+	        const_iterator &operator += (difference_type n) {
+	            it_ += n;
+	            return *this;
+	        }
+	
+	    /// \brief Decrement by \e n the position of the iterator 
+	    /// \return a reference to the const iterator
+	        BOOST_UBLAS_INLINE
+	        const_iterator &operator -= (difference_type n) {
+	            it_ -= n;
+	            return *this;
+	        }
+	
+	    /// \brief Return the different in number of positions between 2 iterators
+	        BOOST_UBLAS_INLINE
+	        difference_type operator - (const const_iterator &it) const {
+	            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	            return it_ - it.it_;
+	        }
+	
+	        /// \brief Dereference an iterator
+	        /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
+	    /// \return a const reference to the value pointed by the iterator
+	        BOOST_UBLAS_INLINE
+	        const_reference operator * () const {
+	            BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
+	            return *it_;
+	        }
+	
+	    /// \brief Dereference an iterator at the n-th forward value
+	    /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
+	        /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
+	    /// \return a const reference
+	        BOOST_UBLAS_INLINE
+	        const_reference operator [] (difference_type n) const {
+	            return *(it_ + n);
+	        }
+	
+	        // Index
+	    /// \brief return the index of the element referenced by the iterator
+	         BOOST_UBLAS_INLINE
+	         size_type index () const {
+	             BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
+	             return it_ - (*this) ().begin ().it_;
+	         }
+
+	         // Assignment
+	         BOOST_UBLAS_INLINE
+	    /// \brief assign the value of an iterator to the iterator	   
+	         const_iterator &operator = (const const_iterator &it) {
+	             container_const_reference<self_type>::assign (&it ());
+	             it_ = it.it_;
+	             return *this;
+	         }
+
+	         // Comparison
+	    /// \brief compare the value of two itetarors
+	    /// \return true if they reference the same element
+	        BOOST_UBLAS_INLINE
+	        bool operator == (const const_iterator &it) const {
+	            BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	            return it_ == it.it_;
+	        }
+
+	
+	    /// \brief compare the value of two iterators
+	    /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
+	         BOOST_UBLAS_INLINE
+	         bool operator < (const const_iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ < it.it_;
+	         }
+
+	     private:
+	         const_subiterator_type it_;
+
+	         friend class iterator;
+	     };
+#endif
+
+	/// \brief return an iterator on the first element of the vector
+	    BOOST_UBLAS_INLINE
+	    const_iterator begin () const {
+	        return find (0);
+	    }
+
+    /// \brief return an iterator on the first element of the vector
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+
+	/// \brief return an iterator after the last element of the vector
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (data_.size ());
+        }
+
+    /// \brief return an iterator after the last element of the vector
+         BOOST_UBLAS_INLINE
+         const_iterator cend () const {
+             return end ();
+         }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	     class iterator:
+	         public container_reference<vector>,
+	         public random_access_iterator_base<dense_random_access_iterator_tag,
+	                                            iterator, value_type, difference_type> {
+	     public:
+	         typedef typename vector::difference_type difference_type;
+	         typedef typename vector::value_type value_type;
+	         typedef typename vector::reference reference;
+	         typedef typename vector::pointer pointer;
+
+
+	         // Construction and destruction
+	         BOOST_UBLAS_INLINE
+	         iterator ():
+	             container_reference<self_type> (), it_ () {}
+	         BOOST_UBLAS_INLINE
+	         iterator (self_type &v, const subiterator_type &it):
+	             container_reference<self_type> (v), it_ (it) {}
+
+	         // Arithmetic
+	         BOOST_UBLAS_INLINE
+	         iterator &operator ++ () {
+	             ++ it_;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         iterator &operator -- () {
+	             -- it_;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         iterator &operator += (difference_type n) {
+	             it_ += n;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         iterator &operator -= (difference_type n) {
+	             it_ -= n;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         difference_type operator - (const iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ - it.it_;
+	         }
+
+	         // Dereference
+	         BOOST_UBLAS_INLINE
+	         reference operator * () const {
+	             BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
+	             return *it_;
+	         }
+	         BOOST_UBLAS_INLINE
+	         reference operator [] (difference_type n) const {
+	             return *(it_ + n);
+	         }
+
+	         // Index
+	         BOOST_UBLAS_INLINE
+	         size_type index () const {
+	             BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
+	             return it_ - (*this) ().begin ().it_;
+	         }
+
+	         // Assignment
+	         BOOST_UBLAS_INLINE
+	         iterator &operator = (const iterator &it) {
+	             container_reference<self_type>::assign (&it ());
+	             it_ = it.it_;
+	             return *this;
+	         }
+
+	         // Comparison
+	         BOOST_UBLAS_INLINE
+	         bool operator == (const iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ == it.it_;
+	         }
+	         BOOST_UBLAS_INLINE
+	         bool operator < (const iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ < it.it_;
+	         }
+
+	     private:
+	         subiterator_type it_;
+
+	         friend class const_iterator;
+	     };
+#endif
+
+	/// \brief Return an iterator on the first element of the vector
+	    BOOST_UBLAS_INLINE
+	    iterator begin () {
+	        return find (0);
+	    }
+	
+	/// \brief Return an iterator at the end of the vector
+	    BOOST_UBLAS_INLINE
+	    iterator end () {
+	        return find (data_.size ());
+	    }
+	
+	    // Reverse iterator
+	    typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+	    typedef reverse_iterator_base<iterator> reverse_iterator;
+	
+	/// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
+	    BOOST_UBLAS_INLINE
+	    const_reverse_iterator rbegin () const {
+	        return const_reverse_iterator (end ());
+	    }
+	
+    /// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+
+	/// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector) 
+	    BOOST_UBLAS_INLINE
+	    const_reverse_iterator rend () const {
+	        return const_reverse_iterator (begin ());
+	    }
+	
+    /// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+	/// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
+	    BOOST_UBLAS_INLINE
+	    reverse_iterator rbegin () {
+	        return reverse_iterator (end ());
+	    }
+	
+	/// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector) 
+	    BOOST_UBLAS_INLINE
+	    reverse_iterator rend () {
+	        return reverse_iterator (begin ());
+	    }
+	
+	// -------------
+	    // Serialization
+	// -------------
+	
+	/// Serialize a vector into and archive as defined in Boost
+	/// \param ar Archive object. Can be a flat file, an XML file or any other stream
+	/// \param file_version Optional file version (not yet used)
+	     template<class Archive>
+	     void serialize(Archive & ar, const unsigned int /* file_version */){
+	         ar & serialization::make_nvp("data",data_);
+	     }
+
+	 private:
+	     array_type data_;
+	 };
+
+
+#ifdef BOOST_UBLAS_CPP_GE_2011
+     /** \brief A dense vector of values of type \c T.
+      *
+      * For a \f$n\f$-dimensional vector \f$v\f$ and \f$0\leq i < n\f$ every element \f$v_i\f$ is mapped
+      * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c std::array.
+      * Elements are constructed by \c A, which need not initialise their value.
+      *
+      * \tparam T type of the objects stored in the vector (like int, double, complex,...)
+      * \tparam A The type of the storage array of the vector. Default is \c std::array<T>.
+      */
+     template<class T, std::size_t N, class A>
+     class fixed_vector:
+         public vector_container<fixed_vector<T, N, A> > {
+
+         typedef fixed_vector<T, N, A> self_type;
+     public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+         using vector_container<self_type>::operator ();
+#endif
+
+        typedef typename A::size_type       size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef typename type_traits<T>::const_reference const_reference;
+        typedef T &reference;
+        typedef T *pointer;
+        typedef const T *const_pointer;
+        typedef A array_type;
+        typedef const vector_reference<const self_type> const_closure_type;
+        typedef vector_reference<self_type> closure_type;
+        typedef self_type vector_temporary_type;
+        typedef dense_tag storage_category;
+
+        // Construction and destruction
+
+    /// \brief Constructor of a fixed_vector
+        BOOST_UBLAS_INLINE
+        fixed_vector ():
+            vector_container<self_type> (),
+            data_ () {}
+
+    /// \brief Constructor of a fixed_vector by copying from another container
+    /// This type uses the generic name \c array_type within the vector definition.
+    /// \param data container of type \c A
+         BOOST_UBLAS_INLINE
+         fixed_vector (const array_type &data):
+             vector_container<self_type> (),
+             data_ (data) {}
+
+    /// \brief Constructor of a fixed_vector with a unique initial value
+    /// \param init value to assign to each element of the vector
+         BOOST_UBLAS_INLINE
+         fixed_vector (const value_type &init):
+             vector_container<self_type> (),
+             data_ () {
+             data_.fill( init );
+         }
+
+    /// \brief Copy-constructor of a fixed_vector
+    /// \param v is the fixed_vector to be duplicated
+        BOOST_UBLAS_INLINE
+        fixed_vector (const fixed_vector &v):
+            vector_container<self_type> (),
+            data_ (v.data_) {}
+
+    /// \brief Copy-constructor of a vector from a vector_expression
+    /// Depending on the vector_expression, this constructor can have the cost of the computations
+    /// of the expression (trivial to say it, but take it must be taken into account in your complexity calculations).
+    /// \param ae the vector_expression which values will be duplicated into the vector
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        fixed_vector (const vector_expression<AE> &ae):
+            vector_container<self_type> (),
+            data_ ( ) {
+            vector_assign<scalar_assign> (*this, ae);
+        }
+
+        /// \brief Construct a fixed_vector from a list of values
+        /// This constructor enables initialization by using any of:
+        /// fixed_vector<double, 3> v = { 1, 2, 3 } or fixed_vector<double,3> v( {1, 2, 3} ) or fixed_vector<double,3> v( 1, 2, 3 )
+#if defined(BOOST_MSVC)
+        // This may or may not work. Maybe use this for all instead only for MSVC
+        template <typename... U>
+        fixed_vector(U&&... values) :
+            vector_container<self_type> (),
+            data_{{ std::forward<U>(values)... }} {}
+#else
+        template <typename... Types>
+        fixed_vector(value_type v0, Types... vrest) :
+            vector_container<self_type> (),
+            data_{ { v0, vrest... } } {}
+#endif
+
+    // -----------------------
+    // Random Access Container
+    // -----------------------
+
+    /// \brief Return the maximum size of the data container.
+    /// Return the upper bound (maximum size) on the data container. Depending on the container, it can be bigger than the current size of the vector.
+        BOOST_UBLAS_INLINE
+        size_type max_size () const {
+            return data_.max_size ();
+        }
+
+    /// \brief Return true if the vector is empty (\c size==0)
+    /// \return \c true if empty, \c false otherwise
+        BOOST_UBLAS_INLINE
+        const bool &empty () const {
+            return data_.empty();
+        }
+
+    // ---------
+    // Accessors
+    // ---------
+
+    /// \brief Return the size of the vector
+         BOOST_UBLAS_INLINE
+         BOOST_CONSTEXPR size_type size () const{ // should have a const after C++14
+             return data_.size ();
+         }
+
+    // -----------------
+    // Storage accessors
+    // -----------------
+
+    /// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
+         BOOST_UBLAS_INLINE
+         const array_type &data () const {
+             return data_;
+         }
+
+    /// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
+         BOOST_UBLAS_INLINE
+         array_type &data () {
+             return data_;
+         }
+
+    // ---------------
+         // Element support
+    // ---------------
+
+    /// \brief Return a pointer to the element \f$i\f$
+    /// \param i index of the element
+    // XXX this semantic is not the one expected by the name of this method
+         BOOST_UBLAS_INLINE
+         pointer find_element (size_type i) {
+             return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
+         }
+
+    /// \brief Return a const pointer to the element \f$i\f$
+    /// \param i index of the element
+    // XXX  this semantic is not the one expected by the name of this method
+         BOOST_UBLAS_INLINE
+         const_pointer find_element (size_type i) const {
+             BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); // Since std:array doesn't check for bounds
+             return & (data () [i]);
+         }
+
+    // --------------
+         // Element access
+    // --------------
+
+    /// \brief Return a const reference to the element \f$i\f$
+    /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
+    /// \param i index of the element
+         BOOST_UBLAS_INLINE
+         const_reference operator () (size_type i) const {
+             BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
+             return data () [i];
+         }
+
+    /// \brief Return a reference to the element \f$i\f$
+    /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
+    /// \param i index of the element
+         BOOST_UBLAS_INLINE
+         reference operator () (size_type i) {
+             BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
+             return data () [i];
+         }
+
+    /// \brief Return a const reference to the element \f$i\f$
+    /// \param i index of the element
+         BOOST_UBLAS_INLINE
+         const_reference operator [] (size_type i) const {
+             BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
+             return (*this) (i);
+         }
+
+    /// \brief Return a reference to the element \f$i\f$
+    /// \param i index of the element
+         BOOST_UBLAS_INLINE
+         reference operator [] (size_type i) {
+             BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
+             return (*this) (i);
+         }
+
+    // ------------------
+         // Element assignment
+    // ------------------
+
+    /// \brief Set element \f$i\f$ to the value \c t
+    /// \param i index of the element
+    /// \param t reference to the value to be set
+    // XXX semantic of this is to insert a new element and therefore size=size+1 ?
+         BOOST_UBLAS_INLINE
+         reference insert_element (size_type i, const_reference t) {
+             BOOST_UBLAS_CHECK (i < data_.size(), bad_index ());
+             return (data () [i] = t);
+         }
+
+    /// \brief Set element \f$i\f$ to the \e zero value
+    /// \param i index of the element
+         BOOST_UBLAS_INLINE
+         void erase_element (size_type i) {
+             BOOST_UBLAS_CHECK (i < data_.size(), bad_index ());
+             data () [i] = value_type/*zero*/();
+         }
+
+    // -------
+         // Zeroing
+    // -------
+
+    /// \brief Clear the vector, i.e. set all values to the \c zero value.
+         BOOST_UBLAS_INLINE
+         void clear () {
+             std::fill (data ().begin (), data ().end (), value_type/*zero*/());
+         }
+
+         // Assignment
+#ifdef BOOST_UBLAS_MOVE_SEMANTICS
+
+    /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
+    /// \param v is the source vector
+    /// \return a reference to a fixed_vector (i.e. the destination vector)
+         /*! @note "pass by value" the key idea to enable move semantics */
+         BOOST_UBLAS_INLINE
+         fixed_vector &operator = (fixed_vector v) {
+             assign_temporary(v);
+             return *this;
+         }
+#else
+    /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
+    /// \param v is the source fixed_vector
+    /// \return a reference to a fixed_vector (i.e. the destination vector)
+         BOOST_UBLAS_INLINE
+         fixed_vector &operator = (const fixed_vector &v) {
+             data () = v.data ();
+             return *this;
+         }
+#endif
+
+    /// \brief Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
+    /// Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector). This method does not create any temporary.
+    /// \param v is the source vector container
+    /// \return a reference to a vector (i.e. the destination vector)
+         template<class C>          // Container assignment without temporary
+         BOOST_UBLAS_INLINE
+         fixed_vector &operator = (const vector_container<C> &v) {
+             assign (v);
+             return *this;
+         }
+
+    /// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
+    /// \param v is the source fixed_vector
+    /// \return a reference to a fixed_vector (i.e. the destination fixed_vector)
+         BOOST_UBLAS_INLINE
+         fixed_vector &assign_temporary (fixed_vector &v) {
+             swap ( v );
+             return *this;
+         }
+
+    /// \brief Assign the result of a vector_expression to the fixed_vector
+    /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+    /// \tparam AE is the type of the vector_expression
+    /// \param ae is a const reference to the vector_expression
+    /// \return a reference to the resulting fixed_vector
+         template<class AE>
+         BOOST_UBLAS_INLINE
+         fixed_vector &operator = (const vector_expression<AE> &ae) {
+             self_type temporary (ae);
+             return assign_temporary (temporary);
+         }
+
+    /// \brief Assign the result of a vector_expression to the fixed_vector
+    /// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+    /// \tparam AE is the type of the vector_expression
+    /// \param ae is a const reference to the vector_expression
+    /// \return a reference to the resulting fixed_vector
+         template<class AE>
+         BOOST_UBLAS_INLINE
+         fixed_vector &assign (const vector_expression<AE> &ae) {
+             vector_assign<scalar_assign> (*this, ae);
+             return *this;
+         }
+
+    // -------------------
+         // Computed assignment
+    // -------------------
+
+    /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
+    /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+    /// A temporary is created for the computations.
+    /// \tparam AE is the type of the vector_expression
+    /// \param ae is a const reference to the vector_expression
+    /// \return a reference to the resulting fixed_vector
+         template<class AE>
+         BOOST_UBLAS_INLINE
+         fixed_vector &operator += (const vector_expression<AE> &ae) {
+             self_type temporary (*this + ae);
+             return assign_temporary (temporary);
+         }
+
+    /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
+    /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+    /// No temporary is created. Computations are done and stored directly into the resulting vector.
+    /// \tparam AE is the type of the vector_expression
+    /// \param ae is a const reference to the vector_expression
+    /// \return a reference to the resulting vector
+         template<class C>          // Container assignment without temporary
+         BOOST_UBLAS_INLINE
+         fixed_vector &operator += (const vector_container<C> &v) {
+             plus_assign (v);
+             return *this;
+         }
+
+    /// \brief Assign the sum of the fixed_vector and a vector_expression to the fixed_vector
+    /// Assign the sum of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+    /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
+    /// \tparam AE is the type of the vector_expression
+    /// \param ae is a const reference to the vector_expression
+    /// \return a reference to the resulting vector
+         template<class AE>
+         BOOST_UBLAS_INLINE
+         fixed_vector &plus_assign (const vector_expression<AE> &ae) {
+             vector_assign<scalar_plus_assign> (*this, ae);
+             return *this;
+         }
+
+    /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
+    /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+    /// A temporary is created for the computations.
+    /// \tparam AE is the type of the vector_expression
+    /// \param ae is a const reference to the vector_expression
+         template<class AE>
+         BOOST_UBLAS_INLINE
+         fixed_vector &operator -= (const vector_expression<AE> &ae) {
+             self_type temporary (*this - ae);
+             return assign_temporary (temporary);
+         }
+
+    /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
+    /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+    /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
+    /// \tparam AE is the type of the vector_expression
+    /// \param ae is a const reference to the vector_expression
+    /// \return a reference to the resulting vector
+         template<class C>          // Container assignment without temporary
+         BOOST_UBLAS_INLINE
+         fixed_vector &operator -= (const vector_container<C> &v) {
+             minus_assign (v);
+             return *this;
+         }
+
+    /// \brief Assign the difference of the fixed_vector and a vector_expression to the fixed_vector
+    /// Assign the difference of the fixed_vector and a vector_expression to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+    /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
+    /// \tparam AE is the type of the vector_expression
+    /// \param ae is a const reference to the vector_expression
+    /// \return a reference to the resulting fixed_vector
+         template<class AE>
+         BOOST_UBLAS_INLINE
+         fixed_vector &minus_assign (const vector_expression<AE> &ae) {
+             vector_assign<scalar_minus_assign> (*this, ae);
+             return *this;
+         }
+
+    /// \brief Assign the product of the fixed_vector and a scalar to the fixed_vector
+    /// Assign the product of the fixed_vector and a scalar to the fixed_vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+    /// No temporary is created. Computations are done and stored directly into the resulting fixed_vector.
+    /// \tparam AE is the type of the vector_expression
+    /// \param at is a const reference to the scalar
+    /// \return a reference to the resulting fixed_vector
+         template<class AT>
+         BOOST_UBLAS_INLINE
+         fixed_vector &operator *= (const AT &at) {
+             vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+             return *this;
+         }
+
+    /// \brief Assign the division of the fixed_vector by a scalar to the fixed_vector
+    /// Assign the division of the fixed_vector by a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
+    /// No temporary is created. Computations are done and stored directly into the resulting vector.
+    /// \tparam AE is the type of the vector_expression
+    /// \param at is a const reference to the scalar
+    /// \return a reference to the resulting fixed_vector
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        fixed_vector &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+    // --------
+        // Swapping
+    // --------
+
+    /// \brief Swap the content of the fixed_vector with another vector
+    /// \param v is the fixed_vector to be swapped with
+        BOOST_UBLAS_INLINE
+        void swap (fixed_vector &v) {
+            if (this != &v) {
+                data ().swap (v.data ());
+            }
+        }
+
+    /// \brief Swap the content of two fixed_vectors
+    /// \param v1 is the first fixed_vector. It takes values from v2
+    /// \param v2 is the second fixed_vector It takes values from v1
+         BOOST_UBLAS_INLINE
+         friend void swap (fixed_vector &v1, fixed_vector &v2) {
+             v1.swap (v2);
+         }
+
+         // Iterator types
+     private:
+         // Use the storage array iterator
+         typedef typename A::const_iterator const_subiterator_type;
+         typedef typename A::iterator subiterator_type;
+
+     public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+         typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
+         typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
+#else
+         class const_iterator;
+         class iterator;
+#endif
+
+    // --------------
+        // Element lookup
+    // --------------
+
+    /// \brief Return a const iterator to the element \e i
+    /// \param i index of the element
+         BOOST_UBLAS_INLINE
+         const_iterator find (size_type i) const {
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+             return const_iterator (*this, data ().begin () + i);
+#else
+             return const_iterator (*this, i);
+#endif
+         }
+
+    /// \brief Return an iterator to the element \e i
+    /// \param i index of the element
+         BOOST_UBLAS_INLINE
+         iterator find (size_type i) {
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+             return iterator (*this, data ().begin () + i);
+#else
+             return iterator (*this, i);
+#endif
+         }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+         class const_iterator:
+             public container_const_reference<fixed_vector>,
+             public random_access_iterator_base<dense_random_access_iterator_tag,
+                   const_iterator, value_type, difference_type> {
+         public:
+             typedef typename fixed_vector::difference_type difference_type;
+             typedef typename fixed_vector::value_type value_type;
+             typedef typename fixed_vector::const_reference reference;
+             typedef const typename fixed_vector::pointer pointer;
+
+        // ----------------------------
+            // Construction and destruction
+        // ----------------------------
+
+
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &v, const const_subiterator_type &it):
+                container_const_reference<self_type> (v), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE vector:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+        // ----------
+            // Arithmetic
+        // ----------
+
+        /// \brief Increment by 1 the position of the iterator
+        /// \return a reference to the const iterator
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+
+        /// \brief Decrement by 1 the position of the iterator
+        /// \return a reference to the const iterator
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+
+        /// \brief Increment by \e n the position of the iterator
+        /// \return a reference to the const iterator
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+
+        /// \brief Decrement by \e n the position of the iterator
+        /// \return a reference to the const iterator
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+
+        /// \brief Return the different in number of positions between 2 iterators
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ - it.it_;
+            }
+
+            /// \brief Dereference an iterator
+            /// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
+        /// \return a const reference to the value pointed by the iterator
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
+                return *it_;
+            }
+
+        /// \brief Dereference an iterator at the n-th forward value
+        /// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
+            /// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
+        /// \return a const reference
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(it_ + n);
+            }
+
+            // Index
+        /// \brief return the index of the element referenced by the iterator
+             BOOST_UBLAS_INLINE
+             size_type index () const {
+                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
+                 return it_ - (*this) ().begin ().it_;
+             }
+
+             // Assignment
+             BOOST_UBLAS_INLINE
+        /// \brief assign the value of an iterator to the iterator
+             const_iterator &operator = (const const_iterator &it) {
+                 container_const_reference<self_type>::assign (&it ());
+                 it_ = it.it_;
+                 return *this;
+             }
+
+             // Comparison
+        /// \brief compare the value of two itetarors
+        /// \return true if they reference the same element
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+
+
+        /// \brief compare the value of two iterators
+        /// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
+             BOOST_UBLAS_INLINE
+             bool operator < (const const_iterator &it) const {
+                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                 return it_ < it.it_;
+             }
+
+         private:
+             const_subiterator_type it_;
+
+             friend class iterator;
+         };
+#endif
+
+    /// \brief return an iterator on the first element of the fixed_vector
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+
+    /// \brief return an iterator on the first element of the fixed_vector
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+
+    /// \brief return an iterator after the last element of the fixed_vector
+         BOOST_UBLAS_INLINE
+         const_iterator end () const {
+             return find (data_.size ());
+         }
+
+    /// \brief return an iterator after the last element of the fixed_vector
+         BOOST_UBLAS_INLINE
+         const_iterator cend () const {
+             return end ();
+         }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+         class iterator:
+             public container_reference<fixed_vector>,
+             public random_access_iterator_base<dense_random_access_iterator_tag,
+                                                iterator, value_type, difference_type> {
+         public:
+             typedef typename fixed_vector::difference_type difference_type;
+             typedef typename fixed_vector::value_type value_type;
+             typedef typename fixed_vector::reference reference;
+             typedef typename fixed_vector::pointer pointer;
+
+
+             // Construction and destruction
+             BOOST_UBLAS_INLINE
+             iterator ():
+                 container_reference<self_type> (), it_ () {}
+             BOOST_UBLAS_INLINE
+             iterator (self_type &v, const subiterator_type &it):
+                 container_reference<self_type> (v), it_ (it) {}
+
+             // Arithmetic
+             BOOST_UBLAS_INLINE
+             iterator &operator ++ () {
+                 ++ it_;
+                 return *this;
+             }
+             BOOST_UBLAS_INLINE
+             iterator &operator -- () {
+                 -- it_;
+                 return *this;
+             }
+             BOOST_UBLAS_INLINE
+             iterator &operator += (difference_type n) {
+                 it_ += n;
+                 return *this;
+             }
+             BOOST_UBLAS_INLINE
+             iterator &operator -= (difference_type n) {
+                 it_ -= n;
+                 return *this;
+             }
+             BOOST_UBLAS_INLINE
+             difference_type operator - (const iterator &it) const {
+                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                 return it_ - it.it_;
+             }
+
+             // Dereference
+             BOOST_UBLAS_INLINE
+             reference operator * () const {
+                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
+                 return *it_;
+             }
+             BOOST_UBLAS_INLINE
+             reference operator [] (difference_type n) const {
+                 return *(it_ + n);
+             }
+
+             // Index
+             BOOST_UBLAS_INLINE
+             size_type index () const {
+                 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
+                 return it_ - (*this) ().begin ().it_;
+             }
+
+             // Assignment
+             BOOST_UBLAS_INLINE
+             iterator &operator = (const iterator &it) {
+                 container_reference<self_type>::assign (&it ());
+                 it_ = it.it_;
+                 return *this;
+             }
+
+             // Comparison
+             BOOST_UBLAS_INLINE
+             bool operator == (const iterator &it) const {
+                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                 return it_ == it.it_;
+             }
+             BOOST_UBLAS_INLINE
+             bool operator < (const iterator &it) const {
+                 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                 return it_ < it.it_;
+             }
+
+         private:
+             subiterator_type it_;
+
+             friend class const_iterator;
+         };
+#endif
+
+    /// \brief Return an iterator on the first element of the fixed_vector
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+
+    /// \brief Return an iterator at the end of the fixed_vector
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (data_.size ());
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+    /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+
+    /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+
+    /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+
+    /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+    /// \brief Return a const reverse iterator before the first element of the reversed fixed_vector (i.e. end() of normal fixed_vector)
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+
+    /// \brief Return a const reverse iterator on the end of the reverse fixed_vector (i.e. first element of the normal fixed_vector)
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    // -------------
+        // Serialization
+    // -------------
+
+    /// Serialize a fixed_vector into and archive as defined in Boost
+    /// \param ar Archive object. Can be a flat file, an XML file or any other stream
+    /// \param file_version Optional file version (not yet used)
+         template<class Archive>
+         void serialize(Archive & ar, const unsigned int /* file_version */){
+             ar & serialization::make_nvp("data",data_);
+         }
+
+     private:
+         array_type data_;
+     };
+
+#endif // BOOST_UBLAS_CPP_GE_2011
+
+	 // --------------------
+	 // Bounded vector class
+	 // --------------------
+
+	 /// \brief a dense vector of values of type \c T, of variable size but with maximum \f$N\f$.
+	 /// A dense vector of values of type \c T, of variable size but with maximum \f$N\f$.  The default constructor 
+	 /// creates the vector with size \f$N\f$. Elements are constructed by the storage type \c bounded_array, which \b need \b not \b initialise their value.
+	 template<class T, std::size_t N>
+	 class bounded_vector:
+	     public vector<T, bounded_array<T, N> > {
+
+	     typedef vector<T, bounded_array<T, N> > vector_type;
+	 public:
+	     typedef typename vector_type::size_type size_type;
+	     static const size_type max_size = N;
+
+	     // Construction and destruction
+	     BOOST_UBLAS_INLINE
+	     bounded_vector ():
+	         vector_type (N) {}
+	     BOOST_UBLAS_INLINE
+	     bounded_vector (size_type size):
+	         vector_type (size) {}
+	     BOOST_UBLAS_INLINE
+	     bounded_vector (const bounded_vector &v):
+	         vector_type (v) {}
+	     template<class A2>              // Allow vector<T,bounded_array<N> construction
+	     BOOST_UBLAS_INLINE
+	     bounded_vector (const vector<T, A2> &v):
+	         vector_type (v) {}
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     bounded_vector (const vector_expression<AE> &ae):
+	         vector_type (ae) {}
+	     BOOST_UBLAS_INLINE
+	     ~bounded_vector () {}
+
+	     // Assignment
+#ifdef BOOST_UBLAS_MOVE_SEMANTICS
+
+	     /*! @note "pass by value" the key idea to enable move semantics */
+	     BOOST_UBLAS_INLINE
+	     bounded_vector &operator = (bounded_vector v) {
+	         vector_type::operator = (v);
+	         return *this;
+	     }
+#else
+	     BOOST_UBLAS_INLINE
+	     bounded_vector &operator = (const bounded_vector &v) {
+	         vector_type::operator = (v);
+	         return *this;
+	     }
+#endif
+	     template<class A2>         // Generic vector assignment
+	     BOOST_UBLAS_INLINE
+	     bounded_vector &operator = (const vector<T, A2> &v) {
+	         vector_type::operator = (v);
+	         return *this;
+	     }
+	     template<class C>          // Container assignment without temporary
+	     BOOST_UBLAS_INLINE
+	     bounded_vector &operator = (const vector_container<C> &v) {
+	         vector_type::operator = (v);
+	         return *this;
+	     }
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     bounded_vector &operator = (const vector_expression<AE> &ae) {
+	         vector_type::operator = (ae);
+	         return *this;
+	     }
+	 };
+
+
+
+	 // -----------------
+	 // Zero vector class
+	 // -----------------
+	 
+	 /// \brief A zero vector of type \c T and a given \c size
+	 /// A zero vector of type \c T and a given \c size. This is a virtual vector in the sense that no memory is allocated 
+	 /// for storing the zero values: it still acts like any other vector. However assigning values to it will not change the zero
+	 /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
+	 template<class T, class ALLOC>
+	 class zero_vector:
+	     public vector_container<zero_vector<T, ALLOC> > {
+
+	     typedef const T *const_pointer;
+	     typedef zero_vector<T, ALLOC> self_type;
+	 public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+	     using vector_container<self_type>::operator ();
+#endif
+	     typedef typename ALLOC::size_type size_type;
+	     typedef typename ALLOC::difference_type difference_type;
+	     typedef T value_type;
+	     typedef const T &const_reference;
+	     typedef T &reference;
+	     typedef const vector_reference<const self_type> const_closure_type;
+	     typedef vector_reference<self_type> closure_type;
+	     typedef sparse_tag storage_category;
+
+	     // Construction and destruction
+	     BOOST_UBLAS_INLINE
+	     zero_vector ():
+	         vector_container<self_type> (),
+	         size_ (0) {}
+	     explicit BOOST_UBLAS_INLINE
+	     zero_vector (size_type size):
+	         vector_container<self_type> (),
+	         size_ (size) {}
+	     BOOST_UBLAS_INLINE
+	     zero_vector (const zero_vector &v):
+	         vector_container<self_type> (),
+	         size_ (v.size_) {}
+
+	     // Accessors
+	     BOOST_UBLAS_INLINE
+	     size_type size () const {
+	         return size_;
+	     }
+
+	     // Resizing
+	     BOOST_UBLAS_INLINE
+	     void resize (size_type size, bool /*preserve*/ = true) {
+	         size_ = size;
+	     }
+
+	     // Element support
+	     BOOST_UBLAS_INLINE
+         const_pointer find_element (size_type /*i*/) const {
+	         return & zero_;
+	     }
+
+	     // Element access
+	     BOOST_UBLAS_INLINE
+	     const_reference operator () (size_type /* i */) const {
+	         return zero_;
+	     }
+
+	     BOOST_UBLAS_INLINE
+	     const_reference operator [] (size_type i) const {
+	         return (*this) (i);
+	     }
+
+	     // Assignment
+	     BOOST_UBLAS_INLINE
+	     zero_vector &operator = (const zero_vector &v) {
+	         size_ = v.size_;
+	         return *this;
+	     }
+	     BOOST_UBLAS_INLINE
+	     zero_vector &assign_temporary (zero_vector &v) {
+	         swap (v);
+	         return *this;
+	     }
+
+	     // Swapping
+	     BOOST_UBLAS_INLINE
+	     void swap (zero_vector &v) {
+	         if (this != &v) {
+	             std::swap (size_, v.size_);
+	         }
+	     }
+	     BOOST_UBLAS_INLINE
+	     friend void swap (zero_vector &v1, zero_vector &v2) {
+	         v1.swap (v2);
+	     }
+
+	     // Iterator types
+	 public:
+	     class const_iterator;
+
+	     // Element lookup
+	     BOOST_UBLAS_INLINE
+	     const_iterator find (size_type /*i*/) const {
+	         return const_iterator (*this);
+	     }
+
+	     class const_iterator:
+	         public container_const_reference<zero_vector>,
+	         public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+	                                            const_iterator, value_type> {
+	     public:
+	         typedef typename zero_vector::difference_type difference_type;
+	         typedef typename zero_vector::value_type value_type;
+	         typedef typename zero_vector::const_reference reference;
+	         typedef typename zero_vector::const_pointer pointer;
+
+	         // Construction and destruction
+	         BOOST_UBLAS_INLINE
+	         const_iterator ():
+	             container_const_reference<self_type> () {}
+	         BOOST_UBLAS_INLINE
+	         const_iterator (const self_type &v):
+	             container_const_reference<self_type> (v) {}
+
+	         // Arithmetic
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator ++ () {
+	             BOOST_UBLAS_CHECK_FALSE (bad_index ());
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator -- () {
+	             BOOST_UBLAS_CHECK_FALSE (bad_index ());
+	             return *this;
+	         }
+
+	         // Dereference
+	         BOOST_UBLAS_INLINE
+	         const_reference operator * () const {
+	             BOOST_UBLAS_CHECK_FALSE (bad_index ());
+	             return zero_;   // arbitary return value
+	         }
+
+	         // Index
+	         BOOST_UBLAS_INLINE
+	         size_type index () const {
+	             BOOST_UBLAS_CHECK_FALSE (bad_index ());
+	             return 0;   // arbitary return value
+	         }
+
+	         // Assignment
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator = (const const_iterator &it) {
+	             container_const_reference<self_type>::assign (&it ());
+	             return *this;
+	         }
+
+	         // Comparison
+	         BOOST_UBLAS_INLINE
+	         bool operator == (const const_iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             detail::ignore_unused_variable_warning(it);
+	             return true;
+	         }
+	     };
+
+	     typedef const_iterator iterator;
+
+	     BOOST_UBLAS_INLINE
+	     const_iterator begin () const {
+	         return const_iterator (*this);
+	     }
+         BOOST_UBLAS_INLINE
+         const_iterator cbegin () const {
+             return begin ();
+         }
+	     BOOST_UBLAS_INLINE
+	     const_iterator end () const {
+	         return const_iterator (*this);
+	     }
+         BOOST_UBLAS_INLINE
+         const_iterator cend () const {
+             return end ();
+         }
+
+	     // Reverse iterator
+	     typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+
+	     BOOST_UBLAS_INLINE
+	     const_reverse_iterator rbegin () const {
+	         return const_reverse_iterator (end ());
+	     }
+         BOOST_UBLAS_INLINE
+         const_reverse_iterator crbegin () const {
+             return rbegin ();
+         }
+	     BOOST_UBLAS_INLINE
+	     const_reverse_iterator rend () const {
+	         return const_reverse_iterator (begin ());
+	     }
+         BOOST_UBLAS_INLINE
+         const_reverse_iterator crend () const {
+             return rend ();
+         }
+
+	      // Serialization
+	     template<class Archive>
+	     void serialize(Archive & ar, const unsigned int /* file_version */){
+	         serialization::collection_size_type s (size_);
+	         ar & serialization::make_nvp("size",s);
+	         if (Archive::is_loading::value) {
+	             size_ = s;
+	         }
+	     }
+
+	 private:
+	     size_type size_;
+	     typedef const value_type const_value_type;
+	     static const_value_type zero_;
+	 };
+
+	 template<class T, class ALLOC>
+	 typename zero_vector<T, ALLOC>::const_value_type zero_vector<T, ALLOC>::zero_ = T(/*zero*/);
+
+
+	 // Unit vector class
+	 /// \brief unit_vector represents a canonical unit vector
+	 /// unit_vector represents a canonical unit vector. The \e k-th unit vector of dimension \f$n\f$ holds 0 for every value \f$u_i\f$ s.t. \f$i \neq k\f$ and 1 when \f$i=k\f$.
+	 /// At construction, the value \e k is given after the dimension of the vector.
+	 /// \tparam T is the type of elements in the vector. They must be 0 and 1 assignable in order for the vector to have its unit-vector semantic.
+	 /// \tparam ALLOC a specific allocator can be specified if needed. Most of the time this parameter is omited.
+	 template<class T, class ALLOC>
+	 class unit_vector:
+	     public vector_container<unit_vector<T, ALLOC> > {
+
+	     typedef const T *const_pointer;
+	     typedef unit_vector<T, ALLOC> self_type;
+	 public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+	     using vector_container<self_type>::operator ();
+#endif
+	     typedef typename ALLOC::size_type size_type;
+	     typedef typename ALLOC::difference_type difference_type;
+	     typedef T value_type;
+	     typedef const T &const_reference;
+	     typedef T &reference;
+	     typedef const vector_reference<const self_type> const_closure_type;
+	     typedef vector_reference<self_type> closure_type;
+	     typedef sparse_tag storage_category;
+
+	     // Construction and destruction
+	/// \brief Simple constructor with dimension and index 0
+	    BOOST_UBLAS_INLINE
+	    unit_vector ():
+	        vector_container<self_type> (),
+	        size_ (0), index_ (0) {}
+	
+	/// \brief Constructor of unit_vector
+	/// \param size is the dimension of the vector
+	/// \param index is the order of the vector
+	    BOOST_UBLAS_INLINE
+	    explicit unit_vector (size_type size, size_type index = 0):
+	        vector_container<self_type> (),
+	        size_ (size), index_ (index) {}
+	
+	/// \brief Copy-constructor
+	    BOOST_UBLAS_INLINE
+	    unit_vector (const unit_vector &v):
+	        vector_container<self_type> (),
+	        size_ (v.size_), index_ (v.index_) {}
+	
+	    // Accessors
+	//----------
+	
+	/// \brief Return the size (dimension) of the vector
+	    BOOST_UBLAS_INLINE
+	    size_type size () const {
+	        return size_;
+	    }
+	
+	/// \brief Return the order of the unit vector
+	    BOOST_UBLAS_INLINE
+	    size_type index () const {
+	        return index_;
+	    }
+	
+	    // Resizing
+	// --------
+	
+	/// \brief Resize the vector. The values are preserved by default (i.e. the index does not change)
+	/// \param size is the new size of the vector
+	    BOOST_UBLAS_INLINE
+	    void resize (size_type size, bool /*preserve*/ = true) {
+	        size_ = size;
+	    }
+	
+	    // Element support
+	// ---------------
+	
+	/// \brief Return a const pointer to the element of index i
+	     BOOST_UBLAS_INLINE
+	     const_pointer find_element (size_type i) const {
+	         if (i == index_)
+	             return & one_;
+	         else
+	             return & zero_;
+	     }
+
+	     // Element access
+	     BOOST_UBLAS_INLINE
+	     const_reference operator () (size_type i) const {
+	         if (i == index_)
+	             return one_;
+	         else
+	             return zero_;
+	     }
+
+	     BOOST_UBLAS_INLINE
+	     const_reference operator [] (size_type i) const {
+	         return (*this) (i);
+	     }
+
+	     // Assignment
+	     BOOST_UBLAS_INLINE
+	     unit_vector &operator = (const unit_vector &v) {
+	         size_ = v.size_;
+	         index_ = v.index_;
+	         return *this;
+	     }
+	     BOOST_UBLAS_INLINE
+	     unit_vector &assign_temporary (unit_vector &v) {
+	         swap (v);
+	         return *this;
+	     }
+
+	     // Swapping
+	     BOOST_UBLAS_INLINE
+	     void swap (unit_vector &v) {
+	         if (this != &v) {
+	             std::swap (size_, v.size_);
+	             std::swap (index_, v.index_);
+	         }
+	     }
+	     BOOST_UBLAS_INLINE
+	     friend void swap (unit_vector &v1, unit_vector &v2) {
+	         v1.swap (v2);
+	     }
+
+	     // Iterator types
+	 private:
+	     // Use bool to indicate begin (one_ as value)
+	     typedef bool const_subiterator_type;
+	 public:
+	     class const_iterator;
+
+	     // Element lookup
+	     BOOST_UBLAS_INLINE
+	     const_iterator find (size_type i) const {
+	         return const_iterator (*this, i <= index_);
+	     }
+
+	     class const_iterator:
+	         public container_const_reference<unit_vector>,
+	         public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+	                                            const_iterator, value_type> {
+	     public:
+	         typedef typename unit_vector::difference_type difference_type;
+	         typedef typename unit_vector::value_type value_type;
+	         typedef typename unit_vector::const_reference reference;
+	         typedef typename unit_vector::const_pointer pointer;
+
+	         // Construction and destruction
+	         BOOST_UBLAS_INLINE
+	         const_iterator ():
+	             container_const_reference<unit_vector> (), it_ () {}
+	         BOOST_UBLAS_INLINE
+	         const_iterator (const unit_vector &v, const const_subiterator_type &it):
+	             container_const_reference<unit_vector> (v), it_ (it) {}
+
+	         // Arithmetic
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator ++ () {
+	             BOOST_UBLAS_CHECK (it_, bad_index ());
+	             it_ = !it_;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator -- () {
+	             BOOST_UBLAS_CHECK (!it_, bad_index ());
+	             it_ = !it_;
+	             return *this;
+	         }
+
+	         // Dereference
+	         BOOST_UBLAS_INLINE
+	         const_reference operator * () const {
+	             BOOST_UBLAS_CHECK (it_, bad_index ());
+	             return one_;
+	         }
+
+	         // Index
+	         BOOST_UBLAS_INLINE
+	         size_type index () const {
+	             BOOST_UBLAS_CHECK (it_, bad_index ());
+	             return (*this) ().index_;
+	         }
+
+	         // Assignment
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator = (const const_iterator &it) {
+	             container_const_reference<unit_vector>::assign (&it ());
+	             it_ = it.it_;
+	             return *this;
+	         }
+
+	         // Comparison
+	         BOOST_UBLAS_INLINE
+	         bool operator == (const const_iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ == it.it_;
+	         }
+
+	     private:
+	         const_subiterator_type it_;
+	     };
+
+	     typedef const_iterator iterator;
+
+	     BOOST_UBLAS_INLINE
+	     const_iterator begin () const {
+	         return const_iterator (*this, true);
+	     }
+         BOOST_UBLAS_INLINE
+         const_iterator cbegin () const {
+             return begin ();
+         }
+	     BOOST_UBLAS_INLINE
+	     const_iterator end () const {
+	         return const_iterator (*this, false);
+	     }
+         BOOST_UBLAS_INLINE
+         const_iterator cend () const {
+             return end ();
+         }
+
+	     // Reverse iterator
+	     typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+
+	     BOOST_UBLAS_INLINE
+	     const_reverse_iterator rbegin () const {
+	         return const_reverse_iterator (end ());
+	     }
+         BOOST_UBLAS_INLINE
+         const_reverse_iterator crbegin () const {
+             return rbegin ();
+         }
+	     BOOST_UBLAS_INLINE
+	     const_reverse_iterator rend () const {
+	         return const_reverse_iterator (begin ());
+	     }
+         BOOST_UBLAS_INLINE
+         const_reverse_iterator crend () const {
+             return rend ();
+         }
+
+	      // Serialization
+	     template<class Archive>
+	     void serialize(Archive & ar, const unsigned int /* file_version */){
+	         serialization::collection_size_type s (size_);
+	         ar & serialization::make_nvp("size",s);
+	         if (Archive::is_loading::value) {
+	             size_ = s;
+	         }
+	         ar & serialization::make_nvp("index", index_);
+	     }
+
+	 private:
+	     size_type size_;
+	     size_type index_;
+	     typedef const value_type const_value_type;
+	     static const_value_type zero_;
+	     static const_value_type one_;
+	 };
+
+	 template<class T, class ALLOC>
+	 typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::zero_ = T(/*zero*/);
+	 template<class T, class ALLOC>
+	 typename unit_vector<T, ALLOC>::const_value_type unit_vector<T, ALLOC>::one_ (1);  // ISSUE: need 'one'-traits here
+
+	 /// \brief A scalar (i.e. unique value) vector of type \c T and a given \c size
+	 /// A scalar (i.e. unique value) vector of type \c T and a given \c size. This is a virtual vector in the sense that no memory is allocated 
+	 /// for storing the unique value more than once: it still acts like any other vector. However assigning a new value will change all the value at once.
+	 /// vector into a normal vector. It must first be assigned to another normal vector by any suitable means. Its memory footprint is constant.
+	 /// \tparam T type of the objects stored in the vector: it can be anything even if most of the time, scalar types will be used like \c double or \c int. Complex types can be used, or even classes like boost::interval.
+	 template<class T, class ALLOC>
+	 class scalar_vector:
+	     public vector_container<scalar_vector<T, ALLOC> > {
+
+	     typedef const T *const_pointer;
+	     typedef scalar_vector<T, ALLOC> self_type;
+	 public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+	     using vector_container<self_type>::operator ();
+#endif
+	     typedef typename ALLOC::size_type size_type;
+	     typedef typename ALLOC::difference_type difference_type;
+	     typedef T value_type;
+	     typedef const T &const_reference;
+	     typedef T &reference;
+	     typedef const vector_reference<const self_type> const_closure_type;
+	     typedef vector_reference<self_type> closure_type;
+	     typedef dense_tag storage_category;
+
+	     // Construction and destruction
+	     BOOST_UBLAS_INLINE
+	     scalar_vector ():
+	         vector_container<self_type> (),
+	         size_ (0), value_ () {}
+	     BOOST_UBLAS_INLINE
+	     explicit scalar_vector (size_type size, const value_type &value = value_type(1)):
+	         vector_container<self_type> (),
+	         size_ (size), value_ (value) {}
+	     BOOST_UBLAS_INLINE
+	     scalar_vector (const scalar_vector &v):
+	         vector_container<self_type> (),
+	         size_ (v.size_), value_ (v.value_) {}
+
+	     // Accessors
+	     BOOST_UBLAS_INLINE
+	     size_type size () const {
+	         return size_;
+	     }
+
+	     // Resizing
+	     BOOST_UBLAS_INLINE
+	     void resize (size_type size, bool /*preserve*/ = true) {
+	         size_ = size;
+	     }
+
+	     // Element support
+	     BOOST_UBLAS_INLINE
+	     const_pointer find_element (size_type /*i*/) const {
+	         return & value_;
+	     }
+
+	     // Element access
+	     BOOST_UBLAS_INLINE
+	     const_reference operator () (size_type /*i*/) const {
+	         return value_;
+	     }
+
+	     BOOST_UBLAS_INLINE
+	     const_reference operator [] (size_type /*i*/) const {
+	         return value_;
+	     }
+
+	     // Assignment
+	     BOOST_UBLAS_INLINE
+	     scalar_vector &operator = (const scalar_vector &v) {
+	         size_ = v.size_;
+	         value_ = v.value_;
+	         return *this;
+	     }
+	     BOOST_UBLAS_INLINE
+	     scalar_vector &assign_temporary (scalar_vector &v) {
+	         swap (v);
+	         return *this;
+	     }
+
+	     // Swapping
+	     BOOST_UBLAS_INLINE
+	     void swap (scalar_vector &v) {
+	         if (this != &v) {
+	             std::swap (size_, v.size_);
+	             std::swap (value_, v.value_);
+	         }
+	     }
+	     BOOST_UBLAS_INLINE
+	     friend void swap (scalar_vector &v1, scalar_vector &v2) {
+	         v1.swap (v2);
+	     }
+
+	     // Iterator types
+	 private:
+	     // Use an index
+	     typedef size_type const_subiterator_type;
+
+	 public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	     typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> iterator;
+	     typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
+#else
+	     class const_iterator;
+#endif
+
+	     // Element lookup
+	     BOOST_UBLAS_INLINE
+	     const_iterator find (size_type i) const {
+	         return const_iterator (*this, i);
+	     }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	     class const_iterator:
+	         public container_const_reference<scalar_vector>,
+	         public random_access_iterator_base<dense_random_access_iterator_tag,
+	                                            const_iterator, value_type> {
+	     public:
+	         typedef typename scalar_vector::difference_type difference_type;
+	         typedef typename scalar_vector::value_type value_type;
+	         typedef typename scalar_vector::const_reference reference;
+	         typedef typename scalar_vector::const_pointer pointer;
+
+	         // Construction and destruction
+	         BOOST_UBLAS_INLINE
+	         const_iterator ():
+	             container_const_reference<scalar_vector> (), it_ () {}
+	         BOOST_UBLAS_INLINE
+	         const_iterator (const scalar_vector &v, const const_subiterator_type &it):
+	             container_const_reference<scalar_vector> (v), it_ (it) {}
+
+	         // Arithmetic
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator ++ () {
+	             ++ it_;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator -- () {
+	             -- it_;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator += (difference_type n) {
+	             it_ += n;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator -= (difference_type n) {
+	             it_ -= n;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         difference_type operator - (const const_iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ - it.it_;
+	         }
+
+	         // Dereference
+	         BOOST_UBLAS_INLINE
+	         const_reference operator * () const {
+	             BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
+	             return (*this) () (index ());
+	         }
+	         BOOST_UBLAS_INLINE
+	         const_reference operator [] (difference_type n) const {
+	             return *(*this + n);
+	         }
+
+	         // Index
+	         BOOST_UBLAS_INLINE
+	         size_type index () const {
+	             BOOST_UBLAS_CHECK (it_ < (*this) ().size (), bad_index ());
+	             return it_;
+	         }
+
+	         // Assignment
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator = (const const_iterator &it) {
+	             container_const_reference<scalar_vector>::assign (&it ());
+	             it_ = it.it_;
+	             return *this;
+	         }
+
+	         // Comparison
+	         BOOST_UBLAS_INLINE
+	         bool operator == (const const_iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ == it.it_;
+	         }
+	         BOOST_UBLAS_INLINE
+	         bool operator < (const const_iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ < it.it_;
+	         }
+
+	     private:
+	         const_subiterator_type it_;
+	     };
+
+	     typedef const_iterator iterator;
+#endif
+
+	     BOOST_UBLAS_INLINE
+	     const_iterator begin () const {
+	         return find (0);
+	     }
+         BOOST_UBLAS_INLINE
+         const_iterator cbegin () const {
+             return begin ();
+         }
+	     BOOST_UBLAS_INLINE
+	     const_iterator end () const {
+	         return find (size_);
+	     }
+         BOOST_UBLAS_INLINE
+         const_iterator cend () const {
+             return end ();
+         }
+
+	     // Reverse iterator
+	     typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+
+	     BOOST_UBLAS_INLINE
+	     const_reverse_iterator rbegin () const {
+	         return const_reverse_iterator (end ());
+	     }
+         BOOST_UBLAS_INLINE
+         const_reverse_iterator crbegin () const {
+             return rbegin ();
+         }
+	     BOOST_UBLAS_INLINE
+	     const_reverse_iterator rend () const {
+	         return const_reverse_iterator (begin ());
+	     }
+         BOOST_UBLAS_INLINE
+         const_reverse_iterator crend () const {
+             return rend ();
+         }
+
+	      // Serialization
+	     template<class Archive>
+	     void serialize(Archive & ar, const unsigned int /* file_version */){
+	         serialization::collection_size_type s (size_);
+	         ar & serialization::make_nvp("size",s);
+	         if (Archive::is_loading::value) {
+	             size_ = s;
+	         }
+	         ar & serialization::make_nvp("value", value_);
+	     }
+
+	 private:
+	     size_type size_;
+	     value_type value_;
+	 };
+
+	 // ------------------------
+	 // Array based vector class
+	 // ------------------------
+
+	 /// \brief A dense vector of values of type \c T with the given \c size. The data is stored as an ordinary C++ array \c T \c data_[M]
+	 template<class T, std::size_t N>
+	 class c_vector:
+	     public vector_container<c_vector<T, N> > {
+
+	     typedef c_vector<T, N> self_type;
+	 public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+	     using vector_container<self_type>::operator ();
+#endif
+	     typedef std::size_t size_type;
+	     typedef std::ptrdiff_t difference_type;
+	     typedef T value_type;
+	     typedef const T &const_reference;
+	     typedef T &reference;
+	     typedef value_type array_type[N];
+	     typedef T *pointer;
+	     typedef const T *const_pointer;
+	     typedef const vector_reference<const self_type> const_closure_type;
+	     typedef vector_reference<self_type> closure_type;
+	     typedef self_type vector_temporary_type;
+	     typedef dense_tag storage_category;
+
+	     // Construction and destruction
+	     BOOST_UBLAS_INLINE
+	     c_vector ():
+	         size_ (N) /* , data_ () */ {}
+	     explicit BOOST_UBLAS_INLINE
+	     c_vector (size_type size):
+	         size_ (size) /* , data_ () */ {
+	         if (size_ > N)
+                 bad_size ().raise ();
+	     }
+	     BOOST_UBLAS_INLINE
+	     c_vector (const c_vector &v):
+	         size_ (v.size_) /* , data_ () */ {
+	         if (size_ > N)
+                 bad_size ().raise ();
+	         assign(v);
+	     }
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     c_vector (const vector_expression<AE> &ae):
+	         size_ (ae ().size ()) /* , data_ () */ {
+	         if (size_ > N)
+                 bad_size ().raise ();
+	         vector_assign<scalar_assign> (*this, ae);
+	     }
+
+	     // Accessors
+	     BOOST_UBLAS_INLINE
+	     size_type size () const {
+	         return size_;
+	     }
+	     BOOST_UBLAS_INLINE
+	     const_pointer data () const {
+	         return data_;
+	     }
+	     BOOST_UBLAS_INLINE
+	     pointer data () {
+	         return data_;
+	     }
+
+	     // Resizing
+	     BOOST_UBLAS_INLINE
+         void resize (size_type size, bool /*preserve*/ = true) {
+	         if (size > N)
+                 bad_size ().raise ();
+	         size_ = size;
+	     }
+
+	     // Element support
+	     BOOST_UBLAS_INLINE
+	     pointer find_element (size_type i) {
+	         return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
+	     }
+	     BOOST_UBLAS_INLINE
+	     const_pointer find_element (size_type i) const {
+	         return & data_ [i];
+	     }
+
+	     // Element access
+	     BOOST_UBLAS_INLINE
+	     const_reference operator () (size_type i) const {
+	         BOOST_UBLAS_CHECK (i < size_,  bad_index ());
+	         return data_ [i];
+	     }
+	     BOOST_UBLAS_INLINE
+	     reference operator () (size_type i) {
+	         BOOST_UBLAS_CHECK (i < size_, bad_index ());
+	         return data_ [i];
+	     }
+
+	     BOOST_UBLAS_INLINE
+	     const_reference operator [] (size_type i) const {
+	         return (*this) (i);
+	     }
+	     BOOST_UBLAS_INLINE
+	     reference operator [] (size_type i) {
+	         return (*this) (i);
+	     }
+
+	     // Element assignment
+	     BOOST_UBLAS_INLINE
+	     reference insert_element (size_type i, const_reference t) {
+	         BOOST_UBLAS_CHECK (i < size_, bad_index ());
+	         return (data_ [i] = t);
+	     }
+	     BOOST_UBLAS_INLINE
+	     void erase_element (size_type i) {
+	         BOOST_UBLAS_CHECK (i < size_, bad_index ());
+	         data_ [i] = value_type/*zero*/();
+	     }
+	     
+	     // Zeroing
+	     BOOST_UBLAS_INLINE
+	     void clear () {
+	         std::fill (data_, data_ + size_, value_type/*zero*/());
+	     }
+
+	     // Assignment
+#ifdef BOOST_UBLAS_MOVE_SEMANTICS
+
+	     /*! @note "pass by value" the key idea to enable move semantics */
+	     BOOST_UBLAS_INLINE
+	     c_vector &operator = (c_vector v) {
+	         assign_temporary(v);
+	         return *this;
+	     }
+#else
+	     BOOST_UBLAS_INLINE
+	     c_vector &operator = (const c_vector &v) {
+	         size_ = v.size_;
+	         std::copy (v.data_, v.data_ + v.size_, data_);
+	         return *this;
+	     }
+#endif
+	     template<class C>          // Container assignment without temporary
+	     BOOST_UBLAS_INLINE
+	     c_vector &operator = (const vector_container<C> &v) {
+	         resize (v ().size (), false);
+	         assign (v);
+	         return *this;
+	     }
+	     BOOST_UBLAS_INLINE
+	     c_vector &assign_temporary (c_vector &v) {
+	         swap (v);
+	         return *this;
+	     }
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     c_vector &operator = (const vector_expression<AE> &ae) {
+	         self_type temporary (ae);
+	         return assign_temporary (temporary);
+	     }
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     c_vector &assign (const vector_expression<AE> &ae) {
+	         vector_assign<scalar_assign> (*this, ae);
+	         return *this;
+	     }
+
+	     // Computed assignment
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     c_vector &operator += (const vector_expression<AE> &ae) {
+	         self_type temporary (*this + ae);
+	         return assign_temporary (temporary);
+	     }
+	     template<class C>          // Container assignment without temporary
+	     BOOST_UBLAS_INLINE
+	     c_vector &operator += (const vector_container<C> &v) {
+	         plus_assign (v);
+	         return *this;
+	     }
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     c_vector &plus_assign (const vector_expression<AE> &ae) {
+	         vector_assign<scalar_plus_assign> ( *this, ae);
+	         return *this;
+	     }
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     c_vector &operator -= (const vector_expression<AE> &ae) {
+	         self_type temporary (*this - ae);
+	         return assign_temporary (temporary);
+	     }
+	     template<class C>          // Container assignment without temporary
+	     BOOST_UBLAS_INLINE
+	     c_vector &operator -= (const vector_container<C> &v) {
+	         minus_assign (v);
+	         return *this;
+	     }
+	     template<class AE>
+	     BOOST_UBLAS_INLINE
+	     c_vector &minus_assign (const vector_expression<AE> &ae) {
+	         vector_assign<scalar_minus_assign> (*this, ae);
+	         return *this;
+	     }
+	     template<class AT>
+	     BOOST_UBLAS_INLINE
+	     c_vector &operator *= (const AT &at) {
+	         vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+	         return *this;
+	     }
+	     template<class AT>
+	     BOOST_UBLAS_INLINE
+	     c_vector &operator /= (const AT &at) {
+	         vector_assign_scalar<scalar_divides_assign> (*this, at);
+	         return *this;
+	     }
+
+	     // Swapping
+	     BOOST_UBLAS_INLINE
+	     void swap (c_vector &v) {
+	         if (this != &v) {
+                 BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
+	             std::swap (size_, v.size_);
+	             std::swap_ranges (data_, data_ + size_, v.data_);
+	         }
+	     }
+	     BOOST_UBLAS_INLINE
+	     friend void swap (c_vector &v1, c_vector &v2) {
+	         v1.swap (v2);
+	     }
+
+	     // Iterator types
+	 private:
+	     // Use pointers for iterator
+	     typedef const_pointer const_subiterator_type;
+	     typedef pointer subiterator_type;
+
+	 public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	     typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
+	     typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
+#else
+	     class const_iterator;
+	     class iterator;
+#endif
+
+	     // Element lookup
+	     BOOST_UBLAS_INLINE
+	     const_iterator find (size_type i) const {
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	         return const_iterator (*this, &data_ [i]);
+#else
+	         return const_iterator (*this, i);
+#endif
+	     }
+	     BOOST_UBLAS_INLINE
+	     iterator find (size_type i) {
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	         return iterator (*this, &data_ [i]);
+#else
+	         return iterator (*this, i);
+#endif
+	     }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	     class const_iterator:
+	         public container_const_reference<c_vector>,
+	         public random_access_iterator_base<dense_random_access_iterator_tag,
+	                                            const_iterator, value_type> {
+	     public:
+	         typedef typename c_vector::difference_type difference_type;
+	         typedef typename c_vector::value_type value_type;
+	         typedef typename c_vector::const_reference reference;
+	         typedef typename c_vector::const_pointer pointer;
+
+	         // Construction and destruction
+	         BOOST_UBLAS_INLINE
+	         const_iterator ():
+	             container_const_reference<self_type> (), it_ () {}
+	         BOOST_UBLAS_INLINE
+	         const_iterator (const self_type &v, const const_subiterator_type &it):
+	             container_const_reference<self_type> (v), it_ (it) {}
+	         BOOST_UBLAS_INLINE
+	         const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+	             container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+	         // Arithmetic
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator ++ () {
+	             ++ it_;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator -- () {
+	             -- it_;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator += (difference_type n) {
+	             it_ += n;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator -= (difference_type n) {
+	             it_ -= n;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         difference_type operator - (const const_iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ - it.it_;
+	         }
+
+	         // Dereference
+	         BOOST_UBLAS_INLINE
+	         const_reference operator * () const {
+	             BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
+	             return *it_;
+	         }
+	         BOOST_UBLAS_INLINE
+	         const_reference operator [] (difference_type n) const {
+	             return *(it_ + n);
+	         }
+
+	         // Index
+	         BOOST_UBLAS_INLINE
+	         size_type index () const {
+	             BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
+	             const self_type &v = (*this) ();
+	             return it_ - v.begin ().it_;
+	         }
+
+	         // Assignment
+	         BOOST_UBLAS_INLINE
+	         const_iterator &operator = (const const_iterator &it) {
+	             container_const_reference<self_type>::assign (&it ());
+	             it_ = it.it_;
+	             return *this;
+	         }
+
+	         // Comparison
+	         BOOST_UBLAS_INLINE
+	         bool operator == (const const_iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ == it.it_;
+	         }
+	         BOOST_UBLAS_INLINE
+	         bool operator < (const const_iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ < it.it_;
+	         }
+
+	     private:
+	         const_subiterator_type it_;
+
+	         friend class iterator;
+	     };
+#endif
+
+	     BOOST_UBLAS_INLINE
+	     const_iterator begin () const {
+	         return find (0);
+	     }
+         BOOST_UBLAS_INLINE
+         const_iterator cbegin () const {
+             return begin ();
+         }
+	     BOOST_UBLAS_INLINE
+	     const_iterator end () const {
+	         return find (size_);
+	     }
+         BOOST_UBLAS_INLINE
+         const_iterator cend () const {
+             return end ();
+         }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+	     class iterator:
+	         public container_reference<c_vector>,
+	         public random_access_iterator_base<dense_random_access_iterator_tag,
+	                                            iterator, value_type> {
+	     public:
+	         typedef typename c_vector::difference_type difference_type;
+	         typedef typename c_vector::value_type value_type;
+	         typedef typename c_vector::reference reference;
+	         typedef typename c_vector::pointer pointer;
+
+	         // Construction and destruction
+	         BOOST_UBLAS_INLINE
+	         iterator ():
+	             container_reference<self_type> (), it_ () {}
+	         BOOST_UBLAS_INLINE
+	         iterator (self_type &v, const subiterator_type &it):
+	             container_reference<self_type> (v), it_ (it) {}
+
+	         // Arithmetic
+	         BOOST_UBLAS_INLINE
+	         iterator &operator ++ () {
+	             ++ it_;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         iterator &operator -- () {
+	             -- it_;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         iterator &operator += (difference_type n) {
+	             it_ += n;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         iterator &operator -= (difference_type n) {
+	             it_ -= n;
+	             return *this;
+	         }
+	         BOOST_UBLAS_INLINE
+	         difference_type operator - (const iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ - it.it_;
+	         }
+
+	         // Dereference
+	         BOOST_UBLAS_INLINE
+	         reference operator * () const {
+	             BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
+	             return *it_;
+	         }
+	         BOOST_UBLAS_INLINE
+	         reference operator [] (difference_type n) const {
+	             return *(it_ + n);
+	         }
+
+	         // Index
+	         BOOST_UBLAS_INLINE
+	         size_type index () const {
+	             BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
+	             // EDG won't allow const self_type it doesn't allow friend access to it_
+	             self_type &v = (*this) ();
+	             return it_ - v.begin ().it_;
+	         }
+
+	         // Assignment
+	         BOOST_UBLAS_INLINE
+	         iterator &operator = (const iterator &it) {
+	             container_reference<self_type>::assign (&it ());
+	             it_ = it.it_;
+	             return *this;
+	         }
+
+	         // Comparison
+	         BOOST_UBLAS_INLINE
+	         bool operator == (const iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ == it.it_;
+	         }
+	         BOOST_UBLAS_INLINE
+	         bool operator < (const iterator &it) const {
+	             BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+	             return it_ < it.it_;
+	         }
+
+	     private:
+	         subiterator_type it_;
+
+	         friend class const_iterator;
+	     };
+#endif
+
+	     BOOST_UBLAS_INLINE
+	     iterator begin () {
+	         return find (0);
+	     }
+	     BOOST_UBLAS_INLINE
+	     iterator end () {
+	         return find (size_);
+	     }
+
+	     // Reverse iterator
+	     typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+	     typedef reverse_iterator_base<iterator> reverse_iterator;
+
+	     BOOST_UBLAS_INLINE
+	     const_reverse_iterator rbegin () const {
+	         return const_reverse_iterator (end ());
+	     }
+         BOOST_UBLAS_INLINE
+         const_reverse_iterator crbegin () const {
+             return rbegin ();
+         }
+	     BOOST_UBLAS_INLINE
+	     const_reverse_iterator rend () const {
+	         return const_reverse_iterator (begin ());
+	     }
+         BOOST_UBLAS_INLINE
+         const_reverse_iterator crend () const {
+             return rend ();
+         }
+	     BOOST_UBLAS_INLINE
+	     reverse_iterator rbegin () {
+	         return reverse_iterator (end ());
+	     }
+	     BOOST_UBLAS_INLINE
+	     reverse_iterator rend () {
+	         return reverse_iterator (begin ());
+	     }
+
+	     // Serialization
+	     template<class Archive>
+	     void serialize(Archive & ar, const unsigned int /* file_version */){
+	         serialization::collection_size_type s (size_);
+	         ar & serialization::make_nvp("size",s);
+	         
+	         // copy the value back if loading
+	         if (Archive::is_loading::value) {
+	           if (s > N) bad_size("too large size in bounded_vector::load()\n").raise();
+	           size_ = s;
+	         }
+	         // ISSUE: this writes the full array
+	         ar & serialization::make_nvp("data",data_);
+	     }
+
+	 private:
+	     size_type size_;
+	     array_type data_;
+	 };
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/vector_expression.hpp b/include/boost/numeric/ublas/vector_expression.hpp
new file mode 100644
index 0000000..aebb403
--- /dev/null
+++ b/include/boost/numeric/ublas/vector_expression.hpp
@@ -0,0 +1,1752 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_VECTOR_EXPRESSION_
+#define _BOOST_UBLAS_VECTOR_EXPRESSION_
+
+#include <boost/numeric/ublas/expression_types.hpp>
+
+
+// Expression templates based on ideas of Todd Veldhuizen and Geoffrey Furnish
+// Iterators based on ideas of Jeremy Siek
+//
+// Classes that model the Vector Expression concept
+
+namespace boost { namespace numeric { namespace ublas {
+
+    template<class E>
+    class vector_reference:
+        public vector_expression<vector_reference<E> > {
+
+        typedef vector_reference<E> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<vector_reference<E> >::operator ();
+#endif
+        typedef typename E::size_type size_type;
+        typedef typename E::difference_type difference_type;
+        typedef typename E::value_type value_type;
+        typedef typename E::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<E>,
+                                          typename E::const_reference,
+                                          typename E::reference>::type reference;
+        typedef E referred_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename E::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        explicit vector_reference (referred_type &e):
+            e_ (e) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return expression ().size ();
+        }
+
+    public:
+        // Expression accessors - const correct
+        BOOST_UBLAS_INLINE
+        const referred_type &expression () const {
+            return e_;
+        }
+        BOOST_UBLAS_INLINE
+        referred_type &expression () {
+            return e_;
+        }
+
+    public:
+        // Element access
+#ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return expression () (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            return expression () (i);
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return expression () [i];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return expression () [i];
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) const {
+            return expression () (i);
+        }
+
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) const {
+            return expression () [i];
+        }
+#endif
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        vector_reference &operator = (const vector_reference &v) {
+            expression ().operator = (v);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_reference &operator = (const vector_expression<AE> &ae) {
+            expression ().operator = (ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_reference &assign (const vector_expression<AE> &ae) {
+            expression ().assign (ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_reference &operator += (const vector_expression<AE> &ae) {
+            expression ().operator += (ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_reference &plus_assign (const vector_expression<AE> &ae) {
+            expression ().plus_assign (ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_reference &operator -= (const vector_expression<AE> &ae) {
+            expression ().operator -= (ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_reference &minus_assign (const vector_expression<AE> &ae) {
+            expression ().minus_assign (ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        vector_reference &operator *= (const AT &at) {
+            expression ().operator *= (at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        vector_reference &operator /= (const AT &at) {
+            expression ().operator /= (at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (vector_reference &v) {
+            expression ().swap (v.expression ());
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const vector_reference &vr) const {
+            return &(*this).e_ == &vr.e_;
+        }
+
+        // Iterator types
+        typedef typename E::const_iterator const_iterator;
+        typedef typename boost::mpl::if_<boost::is_const<E>,
+                                          typename E::const_iterator,
+                                          typename E::iterator>::type iterator;
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+            return expression ().find (i);
+        }
+        BOOST_UBLAS_INLINE
+        iterator find (size_type i) {
+            return expression ().find (i);
+        }
+
+        // Iterator is the iterator of the referenced expression.
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return expression ().begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return expression ().end ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return expression ().begin ();
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return expression ().end ();
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        referred_type &e_;
+    };
+
+
+    template<class E, class F>
+    class vector_unary:
+        public vector_expression<vector_unary<E, F> > {
+
+        typedef F functor_type;
+        typedef typename boost::mpl::if_<boost::is_same<F, scalar_identity<typename E::value_type> >,
+                                          E,
+                                          const E>::type expression_type;
+        typedef typename boost::mpl::if_<boost::is_const<expression_type>,
+                                          typename E::const_closure_type,
+                                          typename E::closure_type>::type expression_closure_type;
+        typedef vector_unary<E, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<vector_unary<E, F> >::operator ();
+#endif
+        typedef typename E::size_type size_type;
+        typedef typename E::difference_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef typename boost::mpl::if_<boost::is_same<F, scalar_identity<value_type> >,
+                                          typename E::reference,
+                                          value_type>::type reference;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        // May be used as mutable expression.
+        explicit vector_unary (expression_type &e):
+            e_ (e) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return e_.size ();
+        }
+
+    public:
+        // Expression accessors
+        BOOST_UBLAS_INLINE
+        const expression_closure_type &expression () const {
+            return e_;
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return functor_type::apply (e_ (i));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            BOOST_STATIC_ASSERT ((boost::is_same<functor_type, scalar_identity<value_type > >::value));
+            return e_ (i);
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return functor_type::apply (e_ [i]);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            BOOST_STATIC_ASSERT ((boost::is_same<functor_type, scalar_identity<value_type > >::value));
+            return e_ [i];
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const vector_unary &vu) const {
+            return (*this).expression ().same_closure (vu.expression ());
+        }
+
+        // Iterator types
+    private:
+        typedef typename E::const_iterator const_subiterator_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator<const_closure_type, typename const_subiterator_type::iterator_category> const_iterator;
+        typedef const_iterator iterator;
+#else
+        class const_iterator;
+        typedef const_iterator iterator;
+#endif
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            const_subiterator_type it (e_.find (i));
+            return const_iterator (*this, it.index ());
+#else
+            return const_iterator (*this, e_.find (i));
+#endif
+        }
+
+        // Iterator enhances the iterator of the referenced expression
+        // with the unary functor.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<vector_unary>,
+            public iterator_base_traits<typename E::const_iterator::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename E::const_iterator::iterator_category iterator_category;
+            typedef typename vector_unary::difference_type difference_type;
+            typedef typename vector_unary::value_type value_type;
+            typedef typename vector_unary::const_reference reference;
+            typedef typename vector_unary::const_pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &vu, const const_subiterator_type &it):
+                container_const_reference<self_type> (vu), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (*it_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0); 
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+    private:
+        expression_closure_type e_;
+    };
+
+    template<class E, class F>
+    struct vector_unary_traits {
+        typedef vector_unary<E, F> expression_type;
+//FIXME
+// #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type;
+// #else
+//         typedef typename E::vector_temporary_type result_type;
+// #endif
+    };
+
+    // (- v) [i] = - v [i]
+    template<class E> 
+    BOOST_UBLAS_INLINE
+    typename vector_unary_traits<E, scalar_negate<typename E::value_type> >::result_type
+    operator - (const vector_expression<E> &e) {
+        typedef typename vector_unary_traits<E, scalar_negate<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // (conj v) [i] = conj (v [i])
+    template<class E> 
+    BOOST_UBLAS_INLINE
+    typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::result_type
+    conj (const vector_expression<E> &e) {
+        typedef typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // (real v) [i] = real (v [i])
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename vector_unary_traits<E, scalar_real<typename E::value_type> >::result_type
+    real (const vector_expression<E> &e) {
+        typedef typename vector_unary_traits<E, scalar_real<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // (imag v) [i] = imag (v [i])
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename vector_unary_traits<E, scalar_imag<typename E::value_type> >::result_type
+    imag (const vector_expression<E> &e) {
+        typedef typename vector_unary_traits<E, scalar_imag<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // (trans v) [i] = v [i]
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename vector_unary_traits<const E, scalar_identity<typename E::value_type> >::result_type
+    trans (const vector_expression<E> &e) {
+        typedef typename vector_unary_traits<const E, scalar_identity<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename vector_unary_traits<E, scalar_identity<typename E::value_type> >::result_type
+    trans (vector_expression<E> &e) {
+        typedef typename vector_unary_traits<E, scalar_identity<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // (herm v) [i] = conj (v [i])
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::result_type
+    herm (const vector_expression<E> &e) {
+        typedef typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    template<class E1, class E2, class F>
+    class vector_binary:
+        public vector_expression<vector_binary<E1, E2, F> > {
+
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+        typedef F functor_type;
+        typedef typename E1::const_closure_type expression1_closure_type;
+        typedef typename E2::const_closure_type expression2_closure_type;
+        typedef vector_binary<E1, E2, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<vector_binary<E1, E2, F> >::operator ();
+#endif
+        typedef typename promote_traits<typename E1::size_type, typename E2::size_type>::promote_type size_type;
+        typedef typename promote_traits<typename E1::difference_type, typename E2::difference_type>::promote_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        vector_binary (const expression1_type &e1, const expression2_type &e2):
+            e1_ (e1), e2_ (e2) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const { 
+            return BOOST_UBLAS_SAME (e1_.size (), e2_.size ()); 
+        }
+
+    private:
+        // Accessors
+        BOOST_UBLAS_INLINE
+        const expression1_closure_type &expression1 () const {
+            return e1_;
+        }
+        BOOST_UBLAS_INLINE
+        const expression2_closure_type &expression2 () const {
+            return e2_;
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return functor_type::apply (e1_ (i), e2_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return functor_type::apply (e1_ [i], e2_ [i]);
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const vector_binary &vb) const {
+            return (*this).expression1 ().same_closure (vb.expression1 ()) &&
+                   (*this).expression2 ().same_closure (vb.expression2 ());
+        }
+
+        // Iterator types
+    private:
+        typedef typename E1::const_iterator const_subiterator1_type;
+        typedef typename E2::const_iterator const_subiterator2_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef typename iterator_restrict_traits<typename const_subiterator1_type::iterator_category,
+                                                  typename const_subiterator2_type::iterator_category>::iterator_category iterator_category;
+        typedef indexed_const_iterator<const_closure_type, iterator_category> const_iterator;
+        typedef const_iterator iterator;
+#else
+        class const_iterator;
+        typedef const_iterator iterator;
+#endif
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+            const_subiterator1_type it1 (e1_.find (i));
+            const_subiterator1_type it1_end (e1_.find (size ()));
+            const_subiterator2_type it2 (e2_.find (i));
+            const_subiterator2_type it2_end (e2_.find (size ()));
+            i = (std::min) (it1 != it1_end ? it1.index () : size (),
+                          it2 != it2_end ? it2.index () : size ());
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator (*this, i);
+#else
+            return const_iterator (*this, i, it1, it1_end, it2, it2_end);
+#endif
+        }
+
+        // Iterator merges the iterators of the referenced expressions and
+        // enhances them with the binary functor.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<vector_binary>,
+            public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
+                                                                          typename E2::const_iterator::iterator_category>::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
+                                                      typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
+            typedef typename vector_binary::difference_type difference_type;
+            typedef typename vector_binary::value_type value_type;
+            typedef typename vector_binary::const_reference reference;
+            typedef typename vector_binary::const_pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), i_ (), it1_ (), it1_end_ (), it2_ (), it2_end_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &vb, size_type i,
+                            const const_subiterator1_type &it1, const const_subiterator1_type &it1_end,
+                            const const_subiterator2_type &it2, const const_subiterator2_type &it2_end):
+                container_const_reference<self_type> (vb), i_ (i), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {}
+
+        private: 
+            // Dense specializations
+            BOOST_UBLAS_INLINE
+            void increment (dense_random_access_iterator_tag) {
+                ++ i_; ++ it1_; ++ it2_;
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (dense_random_access_iterator_tag) {
+                -- i_; -- it1_; -- it2_;
+            }
+            BOOST_UBLAS_INLINE
+            void increment (dense_random_access_iterator_tag, difference_type n) {
+                i_ += n; it1_ += n; it2_ += n;
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (dense_random_access_iterator_tag, difference_type n) {
+                i_ -= n; it1_ -= n; it2_ -= n;
+            }
+            BOOST_UBLAS_INLINE
+            value_type dereference (dense_random_access_iterator_tag) const {
+                return functor_type::apply (*it1_, *it2_);
+            }
+
+            // Packed specializations
+            BOOST_UBLAS_INLINE
+            void increment (packed_random_access_iterator_tag) {
+                if (it1_ != it1_end_)
+                    if (it1_.index () <= i_)
+                        ++ it1_;
+                if (it2_ != it2_end_)
+                    if (it2_.index () <= i_)
+                        ++ it2_;
+                ++ i_;
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (packed_random_access_iterator_tag) {
+                if (it1_ != it1_end_)
+                    if (i_ <= it1_.index ())
+                        -- it1_;
+                if (it2_ != it2_end_)
+                    if (i_ <= it2_.index ())
+                        -- it2_;
+                -- i_;
+            }
+            BOOST_UBLAS_INLINE
+            void increment (packed_random_access_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    increment (packed_random_access_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    decrement (packed_random_access_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (packed_random_access_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    decrement (packed_random_access_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    increment (packed_random_access_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            value_type dereference (packed_random_access_iterator_tag) const {
+                value_type t1 = value_type/*zero*/();
+                if (it1_ != it1_end_)
+                    if (it1_.index () == i_)
+                        t1 = *it1_;
+                value_type t2 = value_type/*zero*/();
+                if (it2_ != it2_end_)
+                    if (it2_.index () == i_)
+                        t2 = *it2_;
+                return functor_type::apply (t1, t2);
+            }
+
+            // Sparse specializations
+            BOOST_UBLAS_INLINE
+            void increment (sparse_bidirectional_iterator_tag) {
+                size_type index1 = (*this) ().size ();
+                if (it1_ != it1_end_) {
+                    if  (it1_.index () <= i_)
+                        ++ it1_;
+                    if (it1_ != it1_end_)
+                        index1 = it1_.index ();
+                }
+                size_type index2 = (*this) ().size ();
+                if (it2_ != it2_end_) {
+                    if (it2_.index () <= i_)
+                        ++ it2_;
+                    if (it2_ != it2_end_)
+                        index2 = it2_.index ();
+                }
+                i_ = (std::min) (index1, index2);
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (sparse_bidirectional_iterator_tag) {
+                size_type index1 = (*this) ().size ();
+                if (it1_ != it1_end_) {
+                    if (i_ <= it1_.index ())
+                        -- it1_;
+                    if (it1_ != it1_end_)
+                        index1 = it1_.index ();
+                }
+                size_type index2 = (*this) ().size ();
+                if (it2_ != it2_end_) {
+                    if (i_ <= it2_.index ())
+                        -- it2_;
+                    if (it2_ != it2_end_)
+                        index2 = it2_.index ();
+                }
+                i_ = (std::max) (index1, index2);
+            }
+            BOOST_UBLAS_INLINE
+            void increment (sparse_bidirectional_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    increment (sparse_bidirectional_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    decrement (sparse_bidirectional_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            void decrement (sparse_bidirectional_iterator_tag, difference_type n) {
+                while (n > 0) {
+                    decrement (sparse_bidirectional_iterator_tag ());
+                    --n;
+                }
+                while (n < 0) {
+                    increment (sparse_bidirectional_iterator_tag ());
+                    ++n;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            value_type dereference (sparse_bidirectional_iterator_tag) const {
+                value_type t1 = value_type/*zero*/();
+                if (it1_ != it1_end_)
+                    if (it1_.index () == i_)
+                        t1 = *it1_;
+                value_type t2 = value_type/*zero*/();
+                if (it2_ != it2_end_)
+                    if (it2_.index () == i_)
+                        t2 = *it2_;
+                return functor_type::apply (t1, t2);
+            }
+
+        public: 
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                increment (iterator_category ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                decrement (iterator_category ());
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                increment (iterator_category (), n);
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                decrement (iterator_category (), n);
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return index () - it.index ();
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return dereference (iterator_category ());
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return i_;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                i_ = it.i_;
+                it1_ = it.it1_;
+                it1_end_ = it.it1_end_;
+                it2_ = it.it2_;
+                it2_end_ = it.it2_end_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return index () == it.index ();
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return index () < it.index ();
+            }
+
+        private:
+            size_type i_;
+            const_subiterator1_type it1_;
+            const_subiterator1_type it1_end_;
+            const_subiterator2_type it2_;
+            const_subiterator2_type it2_end_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class E1, class E2, class F>
+    struct vector_binary_traits {
+        typedef vector_binary<E1, E2, F> expression_type;
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type; 
+#else
+        typedef typename E1::vector_temporary_type result_type;
+#endif
+    };
+
+    // (v1 + v2) [i] = v1 [i] + v2 [i]
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename vector_binary_traits<E1, E2, scalar_plus<typename E1::value_type, 
+                                                      typename E2::value_type> >::result_type
+    operator + (const vector_expression<E1> &e1,
+                const vector_expression<E2> &e2) {
+        typedef typename vector_binary_traits<E1, E2, scalar_plus<typename E1::value_type,
+                                                                              typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // (v1 - v2) [i] = v1 [i] - v2 [i]
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename vector_binary_traits<E1, E2, scalar_minus<typename E1::value_type,
+                                                       typename E2::value_type> >::result_type
+    operator - (const vector_expression<E1> &e1,
+                const vector_expression<E2> &e2) {
+        typedef typename vector_binary_traits<E1, E2, scalar_minus<typename E1::value_type,
+                                                                               typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // (v1 * v2) [i] = v1 [i] * v2 [i]
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename vector_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type,
+                                                            typename E2::value_type> >::result_type
+    element_prod (const vector_expression<E1> &e1,
+                  const vector_expression<E2> &e2) {
+        typedef typename vector_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type,
+                                                                                    typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    // (v1 / v2) [i] = v1 [i] / v2 [i]
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename vector_binary_traits<E1, E2, scalar_divides<typename E1::value_type,
+                                                         typename E2::value_type> >::result_type
+    element_div (const vector_expression<E1> &e1,
+                 const vector_expression<E2> &e2) {
+        typedef typename vector_binary_traits<E1, E2, scalar_divides<typename E1::value_type,
+                                                                                 typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+
+    template<class E1, class E2, class F>
+    class vector_binary_scalar1:
+        public vector_expression<vector_binary_scalar1<E1, E2, F> > {
+
+        typedef F functor_type;
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+    public:
+        typedef const E1& expression1_closure_type;
+        typedef typename E2::const_closure_type expression2_closure_type;
+    private:
+        typedef vector_binary_scalar1<E1, E2, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<vector_binary_scalar1<E1, E2, F> >::operator ();
+#endif
+        typedef typename E2::size_type size_type;
+        typedef typename E2::difference_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        vector_binary_scalar1 (const expression1_type &e1, const expression2_type &e2):
+            e1_ (e1), e2_ (e2) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return e2_.size ();
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return functor_type::apply (e1_, e2_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return functor_type::apply (e1_, e2_ [i]);
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const vector_binary_scalar1 &vbs1) const {
+            return &e1_ == &(vbs1.e1_) &&
+                   (*this).e2_.same_closure (vbs1.e2_);
+        }
+
+        // Iterator types
+    private:
+        typedef expression1_type const_subiterator1_type;
+        typedef typename expression2_type::const_iterator const_subiterator2_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator;
+        typedef const_iterator iterator;
+#else
+        class const_iterator;
+        typedef const_iterator iterator;
+#endif
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            const_subiterator2_type it (e2_.find (i));
+            return const_iterator (*this, it.index ());
+#else
+            return const_iterator (*this, const_subiterator1_type (e1_), e2_.find (i));
+#endif
+        }
+
+        // Iterator enhances the iterator of the referenced vector expression
+        // with the binary functor.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<vector_binary_scalar1>,
+            public iterator_base_traits<typename E2::const_iterator::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename E2::const_iterator::iterator_category iterator_category;
+            typedef typename vector_binary_scalar1::difference_type difference_type;
+            typedef typename vector_binary_scalar1::value_type value_type;
+            typedef typename vector_binary_scalar1::const_reference reference;
+            typedef typename vector_binary_scalar1::const_pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &vbs, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (vbs), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it2_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it2_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it2_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ - it.it2_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (it1_, *it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it2_.index ();
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ == it.it2_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
+                return it2_ < it.it2_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0); 
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ()); 
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return end ();
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class E1, class E2, class F>
+    struct vector_binary_scalar1_traits {
+        typedef vector_binary_scalar1<E1, E2, F> expression_type;   // allow E1 to be builtin type
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type;
+#else
+        typedef typename E2::vector_temporary_type result_type;
+#endif
+    };
+
+    // (t * v) [i] = t * v [i]
+    template<class T1, class E2>
+    BOOST_UBLAS_INLINE
+    typename enable_if< is_convertible<T1, typename E2::value_type >,    
+    typename vector_binary_scalar1_traits<const T1, E2, scalar_multiplies<T1, typename E2::value_type> >::result_type
+    >::type
+    operator * (const T1 &e1,
+                const vector_expression<E2> &e2) {
+        typedef typename vector_binary_scalar1_traits<const T1, E2, scalar_multiplies<T1, typename E2::value_type> >::expression_type expression_type;
+        return expression_type (e1, e2 ());
+    }
+
+
+    template<class E1, class E2, class F>
+    class vector_binary_scalar2:
+        public vector_expression<vector_binary_scalar2<E1, E2, F> > {
+
+        typedef F functor_type;
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+        typedef typename E1::const_closure_type expression1_closure_type;
+        typedef const E2& expression2_closure_type;
+        typedef vector_binary_scalar2<E1, E2, F> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<vector_binary_scalar2<E1, E2, F> >::operator ();
+#endif
+        typedef typename E1::size_type size_type;
+        typedef typename E1::difference_type difference_type;
+        typedef typename F::result_type value_type;
+        typedef value_type const_reference;
+        typedef const_reference reference;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        vector_binary_scalar2 (const expression1_type &e1, const expression2_type &e2):
+            e1_ (e1), e2_ (e2) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return e1_.size (); 
+        }
+
+    public:
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return functor_type::apply (e1_ (i), e2_);
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return functor_type::apply (e1_ [i], e2_);
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const vector_binary_scalar2 &vbs2) const {
+            return (*this).e1_.same_closure (vbs2.e1_) &&
+                   &e2_ == &(vbs2.e2_);
+        }
+
+        // Iterator types
+    private:
+        typedef typename expression1_type::const_iterator const_subiterator1_type;
+        typedef expression2_type const_subiterator2_type;
+        typedef const value_type *const_pointer;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_const_iterator<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator;
+        typedef const_iterator iterator;
+#else
+        class const_iterator;
+        typedef const_iterator iterator;
+#endif
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            const_subiterator1_type it (e1_.find (i));
+            return const_iterator (*this, it.index ());
+#else
+            return const_iterator (*this, e1_.find (i), const_subiterator2_type (e2_));
+#endif
+        }
+
+        // Iterator enhances the iterator of the referenced vector expression
+        // with the binary functor.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<vector_binary_scalar2>,
+            public iterator_base_traits<typename E1::const_iterator::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename E1::const_iterator::iterator_category iterator_category;
+            typedef typename vector_binary_scalar2::difference_type difference_type;
+            typedef typename vector_binary_scalar2::value_type value_type;
+            typedef typename vector_binary_scalar2::const_reference reference;
+            typedef typename vector_binary_scalar2::const_pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it1_ (), it2_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &vbs, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
+                container_const_reference<self_type> (vbs), it1_ (it1), it2_ (it2) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it1_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it1_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it1_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ - it.it1_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                return functor_type::apply (*it1_, it2_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it1_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it1_ = it.it1_;
+                it2_ = it.it2_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ == it.it1_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                // FIXME we shouldn't compare floats
+                // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
+                return it1_ < it.it1_;
+            }
+
+        private:
+            const_subiterator1_type it1_;
+            const_subiterator2_type it2_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class E1, class E2, class F>
+    struct vector_binary_scalar2_traits {
+        typedef vector_binary_scalar2<E1, E2, F> expression_type;   // allow E2 to be builtin type
+#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
+        typedef expression_type result_type;
+#else
+        typedef typename E1::vector_temporary_type result_type;
+#endif
+    };
+
+    // (v * t) [i] = v [i] * t
+    template<class E1, class T2>
+    BOOST_UBLAS_INLINE
+    typename enable_if< is_convertible<T2, typename E1::value_type >,    
+    typename vector_binary_scalar2_traits<E1, const T2, scalar_multiplies<typename E1::value_type, T2> >::result_type
+    >::type
+    operator * (const vector_expression<E1> &e1,
+                const T2 &e2) {
+        typedef typename vector_binary_scalar2_traits<E1, const T2, scalar_multiplies<typename E1::value_type, T2> >::expression_type expression_type;
+        return expression_type (e1 (), e2);
+    }
+
+    // (v / t) [i] = v [i] / t
+    template<class E1, class T2>
+    BOOST_UBLAS_INLINE
+    typename enable_if< is_convertible<T2, typename E1::value_type >,    
+    typename vector_binary_scalar2_traits<E1, const T2, scalar_divides<typename E1::value_type, T2> >::result_type
+    >::type
+    operator / (const vector_expression<E1> &e1,
+                const T2 &e2) {
+        typedef typename vector_binary_scalar2_traits<E1, const T2, scalar_divides<typename E1::value_type, T2> >::expression_type expression_type;
+        return expression_type (e1 (), e2);
+    }
+
+
+    template<class E, class F>
+    class vector_scalar_unary:
+        public scalar_expression<vector_scalar_unary<E, F> > {
+
+        typedef E expression_type;
+        typedef F functor_type;
+        typedef typename E::const_closure_type expression_closure_type;
+        typedef typename E::const_iterator::iterator_category iterator_category;
+        typedef vector_scalar_unary<E, F> self_type;
+    public:
+        typedef typename F::result_type value_type;
+        typedef typename E::difference_type difference_type;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        explicit vector_scalar_unary (const expression_type &e):
+            e_ (e) {}
+
+    private:
+        // Expression accessors
+        BOOST_UBLAS_INLINE
+        const expression_closure_type &expression () const {
+            return e_;
+        }
+
+    public:
+        BOOST_UBLAS_INLINE
+        operator value_type () const {
+            return evaluate (iterator_category ());
+        }
+
+    private:
+        // Dense random access specialization
+        BOOST_UBLAS_INLINE
+        value_type evaluate (dense_random_access_iterator_tag) const {
+#ifdef BOOST_UBLAS_USE_INDEXING
+            return functor_type::apply (e_);
+#elif BOOST_UBLAS_USE_ITERATING
+            difference_type size = e_.size ();
+            return functor_type::apply (size, e_.begin ());
+#else
+            difference_type size = e_.size ();
+            if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
+                return functor_type::apply (size, e_.begin ());
+            else
+                return functor_type::apply (e_);
+#endif
+        }
+
+        // Packed bidirectional specialization
+        BOOST_UBLAS_INLINE
+        value_type evaluate (packed_random_access_iterator_tag) const {
+            return functor_type::apply (e_.begin (), e_.end ());
+        }
+
+        // Sparse bidirectional specialization
+        BOOST_UBLAS_INLINE
+        value_type evaluate (sparse_bidirectional_iterator_tag) const {
+            return functor_type::apply (e_.begin (), e_.end ());
+        }
+
+    private:
+        expression_closure_type e_;
+    };
+
+    template<class E, class F>
+    struct vector_scalar_unary_traits {
+        typedef vector_scalar_unary<E, F> expression_type;
+#if !defined (BOOST_UBLAS_SIMPLE_ET_DEBUG) && defined (BOOST_UBLAS_USE_SCALAR_ET)
+// FIXME don't define USE_SCALAR_ET other then for testing
+// They do not work for complex types
+         typedef expression_type result_type;
+#else
+         typedef typename F::result_type result_type;
+#endif
+    };
+
+    // sum v = sum (v [i])
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename vector_scalar_unary_traits<E, vector_sum<E> >::result_type
+    sum (const vector_expression<E> &e) {
+        typedef typename vector_scalar_unary_traits<E, vector_sum<E> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // real: norm_1 v = sum (abs (v [i]))
+    // complex: norm_1 v = sum (abs (real (v [i])) + abs (imag (v [i])))
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename vector_scalar_unary_traits<E, vector_norm_1<E> >::result_type
+    norm_1 (const vector_expression<E> &e) {
+        typedef typename vector_scalar_unary_traits<E, vector_norm_1<E> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // real: norm_2 v = sqrt (sum (v [i] * v [i]))
+    // complex: norm_2 v = sqrt (sum (v [i] * conj (v [i])))
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename vector_scalar_unary_traits<E, vector_norm_2<E> >::result_type
+    norm_2 (const vector_expression<E> &e) {
+        typedef typename vector_scalar_unary_traits<E, vector_norm_2<E> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // real: norm_inf v = maximum (abs (v [i]))
+    // complex: norm_inf v = maximum (maximum (abs (real (v [i])), abs (imag (v [i]))))
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename vector_scalar_unary_traits<E, vector_norm_inf<E> >::result_type
+    norm_inf (const vector_expression<E> &e) {
+        typedef typename vector_scalar_unary_traits<E, vector_norm_inf<E> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    // real: index_norm_inf v = minimum (i: abs (v [i]) == maximum (abs (v [i])))
+    template<class E>
+    BOOST_UBLAS_INLINE
+    typename vector_scalar_unary_traits<E, vector_index_norm_inf<E> >::result_type
+    index_norm_inf (const vector_expression<E> &e) {
+        typedef typename vector_scalar_unary_traits<E, vector_index_norm_inf<E> >::expression_type expression_type;
+        return expression_type (e ());
+    }
+
+    template<class E1, class E2, class F>
+    class vector_scalar_binary:
+        public scalar_expression<vector_scalar_binary<E1, E2, F> > {
+
+        typedef E1 expression1_type;
+        typedef E2 expression2_type;
+        typedef F functor_type;
+        typedef typename E1::const_closure_type expression1_closure_type;
+        typedef typename E2::const_closure_type expression2_closure_type;
+        typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
+                                                  typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
+        typedef vector_scalar_binary<E1, E2, F> self_type;
+    public:
+        static const unsigned complexity = 1;
+        typedef typename F::result_type value_type;
+        typedef typename E1::difference_type difference_type;
+        typedef const self_type const_closure_type;
+        typedef const_closure_type closure_type;
+        typedef unknown_storage_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        vector_scalar_binary (const expression1_type &e1, const expression2_type  &e2):
+            e1_ (e1), e2_ (e2) {}
+
+    private:
+        // Accessors
+        BOOST_UBLAS_INLINE
+        const expression1_closure_type &expression1 () const {
+            return e1_;
+        }
+        BOOST_UBLAS_INLINE
+        const expression2_closure_type &expression2 () const {
+            return e2_;
+        }
+
+    public:
+        BOOST_UBLAS_INLINE
+        operator value_type () const {
+            return evaluate (iterator_category ());
+        }
+
+    private:
+        // Dense random access specialization
+        BOOST_UBLAS_INLINE
+        value_type evaluate (dense_random_access_iterator_tag) const {
+            BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
+#ifdef BOOST_UBLAS_USE_INDEXING
+            return functor_type::apply (e1_, e2_);
+#elif BOOST_UBLAS_USE_ITERATING
+            difference_type size = BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
+            return functor_type::apply (size, e1_.begin (), e2_.begin ());
+#else
+            difference_type size = BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
+            if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
+                return functor_type::apply (size, e1_.begin (), e2_.begin ());
+            else
+                return functor_type::apply (e1_, e2_);
+#endif
+        }
+
+        // Packed bidirectional specialization
+        BOOST_UBLAS_INLINE
+        value_type evaluate (packed_random_access_iterator_tag) const {
+            BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
+            return functor_type::apply (e1_.begin (), e1_.end (), e2_.begin (), e2_.end ());
+        }
+
+        // Sparse bidirectional specialization
+        BOOST_UBLAS_INLINE
+        value_type evaluate (sparse_bidirectional_iterator_tag) const {
+            BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
+            return functor_type::apply (e1_.begin (), e1_.end (), e2_.begin (), e2_.end (), sparse_bidirectional_iterator_tag ());
+        }
+
+    private:
+        expression1_closure_type e1_;
+        expression2_closure_type e2_;
+    };
+
+    template<class E1, class E2, class F>
+    struct vector_scalar_binary_traits {
+        typedef vector_scalar_binary<E1, E2, F> expression_type;
+#if !defined (BOOST_UBLAS_SIMPLE_ET_DEBUG) && defined (BOOST_UBLAS_USE_SCALAR_ET)
+// FIXME don't define USE_SCALAR_ET other then for testing
+// They do not work for complex types
+        typedef expression_type result_type;
+#else
+        typedef typename F::result_type result_type;
+#endif
+    };
+
+    // inner_prod (v1, v2) = sum (v1 [i] * v2 [i])
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
+                                                                   typename promote_traits<typename E1::value_type,
+                                                                                           typename E2::value_type>::promote_type> >::result_type
+    inner_prod (const vector_expression<E1> &e1,
+                const vector_expression<E2> &e2) {
+        typedef typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
+                                                                   typename promote_traits<typename E1::value_type,
+                                                                                           typename E2::value_type>::promote_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+    template<class E1, class E2>
+    BOOST_UBLAS_INLINE
+    typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
+                                                                   typename type_traits<typename promote_traits<typename E1::value_type,
+                                                                                                                typename E2::value_type>::promote_type>::precision_type> >::result_type
+    prec_inner_prod (const vector_expression<E1> &e1,
+                     const vector_expression<E2> &e2) {
+        typedef typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
+                                                                   typename type_traits<typename promote_traits<typename E1::value_type,
+                                                                                                                typename E2::value_type>::promote_type>::precision_type> >::expression_type expression_type;
+        return expression_type (e1 (), e2 ());
+    }
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/vector_of_vector.hpp b/include/boost/numeric/ublas/vector_of_vector.hpp
new file mode 100644
index 0000000..de87a66
--- /dev/null
+++ b/include/boost/numeric/ublas/vector_of_vector.hpp
@@ -0,0 +1,1347 @@
+//
+//  Copyright (c) 2003
+//  Gunter Winkler, Joerg Walter
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_VECTOR_OF_VECTOR_
+#define _BOOST_UBLAS_VECTOR_OF_VECTOR_
+
+#include <boost/type_traits.hpp>
+
+#include <boost/numeric/ublas/storage_sparse.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+
+    // uBLAS sparse vector based sparse matrix class
+    // FIXME outer vector can be sparse type but it is completely filled
+    template<class T, class L, class A>
+    class generalized_vector_of_vector:
+        public matrix_container<generalized_vector_of_vector<T, L, A> > {
+
+        typedef T &true_reference;
+        typedef T *pointer;
+        typedef const T *const_pointer;
+        typedef L layout_type;
+        typedef generalized_vector_of_vector<T, L, A> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using matrix_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+#ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE
+        typedef T &reference;
+#else
+        typedef sparse_matrix_element<self_type> reference;
+#endif
+        typedef A array_type;
+        typedef const matrix_reference<const self_type> const_closure_type;
+        typedef matrix_reference<self_type> closure_type;
+        typedef typename A::value_type vector_data_value_type;
+        typedef vector_data_value_type vector_temporary_type;
+        typedef self_type matrix_temporary_type;
+        typedef sparse_tag storage_category;
+        typedef typename L::orientation_category orientation_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector ():
+            matrix_container<self_type> (),
+            size1_ (0), size2_ (0), data_ (1) {
+            const size_type sizeM = layout_type::size_M (size1_, size2_);
+             // create size1+1 empty vector elements
+            data_.insert_element (sizeM, vector_data_value_type ());
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector (size_type size1, size_type size2, size_type non_zeros = 0):
+            matrix_container<self_type> (),
+            size1_ (size1), size2_ (size2), data_ (layout_type::size_M (size1_, size2_) + 1) {
+            const size_type sizeM = layout_type::size_M (size1_, size2_);
+            const size_type sizem = layout_type::size_m (size1_, size2_);
+            for (size_type i = 0; i < sizeM; ++ i) // create size1 vector elements
+                data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);
+            data_.insert_element (sizeM, vector_data_value_type ());
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector (const generalized_vector_of_vector &m):
+            matrix_container<self_type> (),
+            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {
+            storage_invariants ();
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector (const matrix_expression<AE> &ae, size_type non_zeros = 0):
+            matrix_container<self_type> (),
+            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size_M (size1_, size2_) + 1) {
+            const size_type sizeM = layout_type::size_M (size1_, size2_);
+            const size_type sizem = layout_type::size_m (size1_, size2_);
+            for (size_type i = 0; i < sizeM; ++ i) // create size1 vector elements
+                data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);
+            data_.insert_element (sizeM, vector_data_value_type ());
+            storage_invariants ();
+            matrix_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size1 () const {
+            return size1_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type size2 () const {
+            return size2_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz_capacity () const {
+            size_type non_zeros = 0;
+            for (const_vectoriterator_type itv = data_.begin (); itv != data_.end (); ++ itv)
+                non_zeros += (*itv).nnz_capacity ();
+            return non_zeros;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz () const {
+            size_type non_zeros = 0;
+            for (const_vectoriterator_type itv = data_.begin (); itv != data_.end (); ++ itv)
+                non_zeros += (*itv).nnz ();
+            return non_zeros;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const array_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+        // Resizing
+        BOOST_UBLAS_INLINE
+        void resize (size_type size1, size_type size2, bool preserve = true) {
+            const size_type oldM = layout_type::size_M (size1_, size2_);
+            size1_ = size1;
+            size2_ = size2;
+            const size_type sizeM = layout_type::size_M (size1_, size2_);
+            const size_type sizem = layout_type::size_m (size1_, size2_);
+            data ().resize (sizeM + 1, preserve);
+            if (preserve) {
+                for (size_type i = 0; (i <= oldM) && (i < sizeM); ++ i)
+                    ref (data () [i]).resize (sizem, preserve);
+                for (size_type i = oldM+1; i < sizeM; ++ i) // create new vector elements
+                    data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);
+                if (sizeM > oldM) {
+                    data_.insert_element (sizeM, vector_data_value_type ());
+                } else {
+                    ref (data () [sizeM]).resize (0, false);
+                }
+            } else {
+                for (size_type i = 0; i < sizeM; ++ i) 
+                    data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);
+                data_.insert_element (sizeM, vector_data_value_type ());
+            }
+            storage_invariants ();
+        }
+
+        // Element support
+        BOOST_UBLAS_INLINE
+        pointer find_element (size_type i, size_type j) {
+            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i, j));
+        }
+        BOOST_UBLAS_INLINE
+        const_pointer find_element (size_type i, size_type j) const {
+            const size_type elementM = layout_type::index_M (i, j);
+            const size_type elementm = layout_type::index_m (i, j);
+            // optimise: check the storage_type and index directly if element always exists
+            if (boost::is_convertible<typename array_type::storage_category, packed_tag>::value) {
+                return & (data () [elementM] [elementm]);
+            }
+            else {
+                const typename array_type::value_type *pv = data ().find_element (elementM);
+                if (!pv)
+                    return 0;
+                return pv->find_element (elementm);
+            }
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i, size_type j) const {
+            const_pointer p = find_element (i, j);
+            // optimise: check the storage_type and index directly if element always exists
+            if (boost::is_convertible<typename array_type::storage_category, packed_tag>::value) {
+                BOOST_UBLAS_CHECK (p, internal_logic () );
+                return *p;
+            }
+            else {
+                if (p)
+                    return *p;
+                else
+                    return zero_;
+            }
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i, size_type j) {
+#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE
+            return at_element (i, j);
+#else
+            return reference (*this, i, j);
+#endif
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector &operator = (const generalized_vector_of_vector &m) {
+            if (this != &m) {
+                size1_ = m.size1_;
+                size2_ = m.size2_;
+                data () = m.data ();
+            }
+            storage_invariants ();
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector &assign_temporary (generalized_vector_of_vector &m) {
+            swap (m);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector &operator = (const matrix_expression<AE> &ae) {
+            self_type temporary (ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector &assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector& operator += (const matrix_expression<AE> &ae) {
+            self_type temporary (*this + ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector &plus_assign (const matrix_expression<AE> &ae) { 
+            matrix_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector& operator -= (const matrix_expression<AE> &ae) {
+            self_type temporary (*this - ae);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector &minus_assign (const matrix_expression<AE> &ae) {
+            matrix_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector& operator *= (const AT &at) {
+            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        generalized_vector_of_vector& operator /= (const AT &at) {
+            matrix_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (generalized_vector_of_vector &m) {
+            if (this != &m) {
+                std::swap (size1_, m.size1_);
+                std::swap (size2_, m.size2_);
+                data ().swap (m.data ());
+            }
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (generalized_vector_of_vector &m1, generalized_vector_of_vector &m2) {
+            m1.swap (m2);
+        }
+
+        // Sorting
+        void sort () {
+            vectoriterator_type itv (data ().begin ());
+            vectoriterator_type itv_end (data ().end ());
+            while (itv != itv_end) {
+                (*itv).sort ();
+                ++ itv;
+            }
+        }
+
+        // Element insertion and erasure
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, size_type j, const_reference t) {
+            const size_type elementM = layout_type::index_M (i, j);
+            const size_type elementm = layout_type::index_m (i, j);
+            vector_data_value_type& vd (ref (data () [elementM]));
+            storage_invariants ();
+            return vd.insert_element (elementm, t);
+        }
+        BOOST_UBLAS_INLINE
+        void append_element (size_type i, size_type j, const_reference t) {
+            const size_type elementM = layout_type::index_M (i, j);
+            const size_type elementm = layout_type::index_m (i, j);
+            vector_data_value_type& vd (ref (data () [elementM]));
+            storage_invariants ();
+            return vd.append_element (elementm, t);
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i, size_type j) {
+            vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));
+            if (itv == data ().end ())
+                return;
+            (*itv).erase_element (layout_type::index_m (i, j));
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        void clear () {
+            const size_type sizeM = layout_type::size_M (size1_, size2_);
+            // FIXME should clear data () if this is done via value_type/*zero*/() then it is not size preserving
+            for (size_type i = 0; i < sizeM; ++ i)
+                ref (data () [i]).clear ();
+            storage_invariants ();
+        }
+
+        // Iterator types
+    private:
+        // Use vector iterator
+        typedef typename A::const_iterator const_vectoriterator_type;
+        typedef typename A::iterator vectoriterator_type;
+        typedef typename A::value_type::const_iterator const_subiterator_type;
+        typedef typename A::value_type::iterator subiterator_type;
+
+        BOOST_UBLAS_INLINE
+        true_reference at_element (size_type i, size_type j) {
+            return ref (ref (data () [layout_type::index_M (i, j)]) [layout_type::index_m (i, j)]);
+        }
+
+    public:
+        class const_iterator1;
+        class iterator1;
+        class const_iterator2;
+        class iterator2;
+        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
+        typedef reverse_iterator_base1<iterator1> reverse_iterator1;
+        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
+        typedef reverse_iterator_base2<iterator2> reverse_iterator2;
+
+        // Element lookup
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {
+            for (;;) {
+                const_vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));
+                const_vectoriterator_type itv_end (data ().end ());
+                if (itv == itv_end)
+                    return const_iterator1 (*this, rank, i, j, itv_end, (*(-- itv)).end ());
+
+                const_subiterator_type it ((*itv).find (layout_type::index_m (i, j)));
+                const_subiterator_type it_end ((*itv).end ());
+                if (rank == 0)
+                    return const_iterator1 (*this, rank, i, j, itv, it);
+                if (it != it_end && it.index () == layout_type::index_m (i, j))
+                    return const_iterator1 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_i ()) {
+                        if (it == it_end)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        i = it.index ();
+                    } else {
+                        if (i >= size1_)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        ++ i;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_i ()) {
+                        if (it == (*itv).begin ())
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        --it;
+                        i = it.index ();
+                    } else {
+                        if (i == 0)
+                            return const_iterator1 (*this, rank, i, j, itv, it);
+                        -- i;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {
+            for (;;) {
+                vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));
+                vectoriterator_type itv_end (data ().end ());
+                if (itv == itv_end)
+                    return iterator1 (*this, rank, i, j, itv_end, (*(-- itv)).end ());
+
+                subiterator_type it ((*itv).find (layout_type::index_m (i, j)));
+                subiterator_type it_end ((*itv).end ());
+                if (rank == 0)
+                    return iterator1 (*this, rank, i, j, itv, it);
+                if (it != it_end && it.index () == layout_type::index_m (i, j))
+                    return iterator1 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_i ()) {
+                        if (it == it_end)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        i = it.index ();
+                    } else {
+                        if (i >= size1_)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        ++ i;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_i ()) {
+                        if (it == (*itv).begin ())
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        --it;
+                        i = it.index ();
+                    } else {
+                        if (i == 0)
+                            return iterator1 (*this, rank, i, j, itv, it);
+                        -- i;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {
+            for (;;) {
+                const_vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));
+                const_vectoriterator_type itv_end (data ().end ());
+                if (itv == itv_end)
+                    return const_iterator2 (*this, rank, i, j, itv_end, (*(-- itv)).end ());
+
+                const_subiterator_type it ((*itv).find (layout_type::index_m (i, j)));
+                const_subiterator_type it_end ((*itv).end ());
+                if (rank == 0)
+                    return const_iterator2 (*this, rank, i, j, itv, it);
+                if (it != it_end && it.index () == layout_type::index_m (i, j))
+                    return const_iterator2 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_j ()) {
+                        if (it == it_end)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        j = it.index ();
+                    } else {
+                        if (j >= size2_)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        ++ j;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_j ()) {
+                        if (it == (*itv).begin ())
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        --it;
+                        j = it.index ();
+                    } else {
+                        if (j == 0)
+                            return const_iterator2 (*this, rank, i, j, itv, it);
+                        -- j;
+                    }
+                }
+            }
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    
+        iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {
+            for (;;) {
+                vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));
+                vectoriterator_type itv_end (data ().end ());
+                if (itv == itv_end)
+                    return iterator2 (*this, rank, i, j, itv_end, (*(-- itv)).end ());
+
+                subiterator_type it ((*itv).find (layout_type::index_m (i, j)));
+                subiterator_type it_end ((*itv).end ());
+                if (rank == 0)
+                    return iterator2 (*this, rank, i, j, itv, it);
+                if (it != it_end && it.index () == layout_type::index_m (i, j))
+                    return iterator2 (*this, rank, i, j, itv, it);
+                if (direction > 0) {
+                    if (layout_type::fast_j ()) {
+                        if (it == it_end)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        j = it.index ();
+                    } else {
+                        if (j >= size2_)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        ++ j;
+                    }
+                } else /* if (direction < 0)  */ {
+                    if (layout_type::fast_j ()) {
+                        if (it == (*itv).begin ())
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        --it;
+                        j = it.index ();
+                    } else {
+                        if (j == 0)
+                            return iterator2 (*this, rank, i, j, itv, it);
+                        -- j;
+                    }
+                }
+            }
+        }
+
+
+        class const_iterator1:
+            public container_const_reference<generalized_vector_of_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator1, value_type> {
+        public:
+            typedef typename generalized_vector_of_vector::difference_type difference_type;
+            typedef typename generalized_vector_of_vector::value_type value_type;
+            typedef typename generalized_vector_of_vector::const_reference reference;
+            typedef const typename generalized_vector_of_vector::pointer pointer;
+
+            typedef const_iterator2 dual_iterator_type;
+            typedef const_reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator1 ():
+                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const self_type &m, int rank, size_type i, size_type j, const const_vectoriterator_type &itv, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator1 (const iterator1 &it):
+                container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    ++ it_;
+                else {
+                    const self_type &m = (*this) ();
+                    i_ = index1 () + 1;
+                    if (rank_ == 1 && ++ itv_ == m.end1 ().itv_) 
+                        *this = m.find1 (rank_, i_, j_, 1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).begin ();
+                        if (it_ == (*itv_).end () || index2 () != j_)
+                            *this = m.find1 (rank_, i_, j_, 1);
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    -- it_;
+                else {
+                    const self_type &m = (*this) ();
+                    i_ = index1 () - 1;
+                    if (rank_ == 1 && -- itv_ == m.end1 ().itv_)
+                        *this = m.find1 (rank_, i_, j_, -1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).begin ();
+                        if (it_ == (*itv_).end () || index2 () != j_)
+                            *this = m.find1 (rank_, i_, j_, -1);
+                    } 
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return *it_;
+                } else {
+                    return (*this) () (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 begin () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 end () const {
+                const self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator2 cend () const {
+                return end ();
+            }
+
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rbegin () const {
+                return const_reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 rend () const {
+                return const_reverse_iterator2 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator2 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M (itv_.index (), it_.index ()) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M (itv_.index (), it_.index ());
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m (itv_.index (), it_.index ()) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m (itv_.index (), it_.index ());
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator1 &operator = (const const_iterator1 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            const_vectoriterator_type itv_;
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator1 begin1 () const {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cbegin1 () const {
+            return begin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 end1 () const {
+            return find1 (0, size1_, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator1 cend1 () const {
+            return end1 ();
+        }
+
+        class iterator1:
+            public container_reference<generalized_vector_of_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator1, value_type> {
+        public:
+            typedef typename generalized_vector_of_vector::difference_type difference_type;
+            typedef typename generalized_vector_of_vector::value_type value_type;
+            typedef typename generalized_vector_of_vector::true_reference reference;
+            typedef typename generalized_vector_of_vector::pointer pointer;
+
+            typedef iterator2 dual_iterator_type;
+            typedef reverse_iterator2 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator1 ():
+                container_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator1 (self_type &m, int rank, size_type i, size_type j, const vectoriterator_type &itv, const subiterator_type &it):
+                container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator1 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    ++ it_;
+                else {
+                    self_type &m = (*this) ();
+                    i_ = index1 () + 1;
+                    if (rank_ == 1 && ++ itv_ == m.end1 ().itv_)
+                        *this = m.find1 (rank_, i_, j_, 1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).begin ();
+                        if (it_ == (*itv_).end () || index2 () != j_)
+                            *this = m.find1 (rank_, i_, j_, 1);
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator1 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_i ())
+                    -- it_;
+                else {
+                    self_type &m = (*this) ();
+                    i_ = index1 () - 1;
+                    if (rank_ == 1 && -- itv_ == m.end1 ().itv_)
+                        *this = m.find1 (rank_, i_, j_, -1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).begin ();
+                        if (it_ == (*itv_).end () || index2 () != j_)
+                            *this = m.find1 (rank_, i_, j_, -1);
+                    }
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            true_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return *it_;
+                } else {
+                    return (*this) ().at_element (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 begin () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), 0);
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator2 end () const {
+                self_type &m = (*this) ();
+                return m.find2 (1, index1 (), m.size2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rbegin () const {
+                return reverse_iterator2 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator2 rend () const {
+                return reverse_iterator2 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M (itv_.index (), it_.index ()) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M (itv_.index (), it_.index ());
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find1 (0, (*this) ().size1 (), j_), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m (itv_.index (), it_.index ()) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m (itv_.index (), it_.index ());
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            iterator1 &operator = (const iterator1 &it) {
+                container_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator1 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vectoriterator_type itv_;
+            subiterator_type it_;
+            
+            friend class const_iterator1;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator1 begin1 () {
+            return find1 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator1 end1 () {
+            return find1 (0, size1_, 0);
+        }
+
+        class const_iterator2:
+            public container_const_reference<generalized_vector_of_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator2, value_type> {
+        public:
+            typedef typename generalized_vector_of_vector::difference_type difference_type;
+            typedef typename generalized_vector_of_vector::value_type value_type;
+            typedef typename generalized_vector_of_vector::const_reference reference;
+            typedef const typename generalized_vector_of_vector::pointer pointer;
+
+            typedef const_iterator1 dual_iterator_type;
+            typedef const_reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator2 ():
+                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const self_type &m, int rank, size_type i, size_type j, const const_vectoriterator_type &itv, const const_subiterator_type &it):
+                container_const_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator2 (const iterator2 &it):
+                container_const_reference<self_type> (it ()), rank_ (it.rank_), i_ (it.i_), j_ (it.j_), itv_ (it.itv_), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    ++ it_;
+                else {
+                    const self_type &m = (*this) ();
+                    j_ = index2 () + 1;
+                    if (rank_ == 1 && ++ itv_ == m.end2 ().itv_) 
+                        *this = m.find2 (rank_, i_, j_, 1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).begin ();
+                        if (it_ == (*itv_).end () || index1 () != i_)
+                            *this = m.find2 (rank_, i_, j_, 1);
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    -- it_;
+                else {
+                    const self_type &m = (*this) ();
+                    j_ = index2 () - 1;
+                    if (rank_ == 1 && -- itv_ == m.end2 ().itv_)
+                        *this = m.find2 (rank_, i_, j_, -1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).begin ();
+                        if (it_ == (*itv_).end () || index1 () != i_)
+                            *this = m.find2 (rank_, i_, j_, -1);
+                    }
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return *it_;
+                } else {
+                    return (*this) () (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 begin () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cbegin () const {
+                return begin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 end () const {
+                const self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_iterator1 cend () const {
+                return end ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rbegin () const {
+                return const_reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crbegin () const {
+                return rbegin ();
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 rend () const {
+                return const_reverse_iterator1 (begin ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            const_reverse_iterator1 crend () const {
+                return rend ();
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M (itv_.index (), it_.index ()) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M (itv_.index (), it_.index ());
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m (itv_.index (), it_.index ()) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m (itv_.index (), it_.index ());
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            const_iterator2 &operator = (const const_iterator2 &it) {
+                container_const_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            const_vectoriterator_type itv_;
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator2 begin2 () const {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cbegin2 () const {
+            return begin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 end2 () const {
+            return find2 (0, 0, size2_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator2 cend2 () const {
+            return end2 ();
+        }
+
+        class iterator2:
+            public container_reference<generalized_vector_of_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator2, value_type> {
+        public:
+            typedef typename generalized_vector_of_vector::difference_type difference_type;
+            typedef typename generalized_vector_of_vector::value_type value_type;
+            typedef typename generalized_vector_of_vector::true_reference reference;
+            typedef typename generalized_vector_of_vector::pointer pointer;
+
+            typedef iterator1 dual_iterator_type;
+            typedef reverse_iterator1 dual_reverse_iterator_type;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator2 ():
+                container_reference<self_type> (), rank_ (), i_ (), j_ (), itv_ (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator2 (self_type &m, int rank, size_type i, size_type j, const vectoriterator_type &itv, const subiterator_type &it):
+                container_reference<self_type> (m), rank_ (rank), i_ (i), j_ (j), itv_ (itv), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator2 &operator ++ () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    ++ it_;
+                else {
+                    self_type &m = (*this) ();
+                    j_ = index2 () + 1;
+                    if (rank_ == 1 && ++ itv_ == m.end2 ().itv_)
+                        *this = m.find2 (rank_, i_, j_, 1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).begin ();
+                        if (it_ == (*itv_).end () || index1 () != i_)
+                            *this = m.find2 (rank_, i_, j_, 1);
+                    }
+                }
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator2 &operator -- () {
+                if (rank_ == 1 && layout_type::fast_j ())
+                    -- it_;
+                else {
+                    self_type &m = (*this) ();
+                    j_ = index2 () - 1;
+                    if (rank_ == 1 && -- itv_ == m.end2 ().itv_)
+                        *this = m.find2 (rank_, i_, j_, -1);
+                    else if (rank_ == 1) {
+                        it_ = (*itv_).begin ();
+                        if (it_ == (*itv_).end () || index1 () != i_)
+                            *this = m.find2 (rank_, i_, j_, -1);
+                    } 
+                }
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            true_reference operator * () const {
+                BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ());
+                BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ());
+                if (rank_ == 1) {
+                    return *it_;
+                } else {
+                    return (*this) ().at_element (i_, j_);
+                }
+            }
+
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 begin () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, 0, index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            iterator1 end () const {
+                self_type &m = (*this) ();
+                return m.find1 (1, m.size1 (), index2 ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rbegin () const {
+                return reverse_iterator1 (end ());
+            }
+            BOOST_UBLAS_INLINE
+#ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
+            typename self_type::
+#endif
+            reverse_iterator1 rend () const {
+                return reverse_iterator1 (begin ());
+            }
+#endif
+
+            // Indices
+            BOOST_UBLAS_INLINE
+            size_type index1 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_M (itv_.index (), it_.index ()) < (*this) ().size1 (), bad_index ());
+                    return layout_type::index_M (itv_.index (), it_.index ());
+                } else {
+                    return i_;
+                }
+            }
+            BOOST_UBLAS_INLINE
+            size_type index2 () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().find2 (0, i_, (*this) ().size2 ()), bad_index ());
+                if (rank_ == 1) {
+                    BOOST_UBLAS_CHECK (layout_type::index_m (itv_.index (), it_.index ()) < (*this) ().size2 (), bad_index ());
+                    return layout_type::index_m (itv_.index (), it_.index ());
+                } else {
+                    return j_;
+                }
+            }
+
+            // Assignment 
+            BOOST_UBLAS_INLINE
+            iterator2 &operator = (const iterator2 &it) {
+                container_reference<self_type>::assign (&it ());
+                rank_ = it.rank_;
+                i_ = it.i_;
+                j_ = it.j_;
+                itv_ = it.itv_;
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator2 &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                // BOOST_UBLAS_CHECK (rank_ == it.rank_, internal_logic ());
+                if (rank_ == 1 || it.rank_ == 1) {
+                    return it_ == it.it_;
+                } else {
+                    return i_ == it.i_ && j_ == it.j_;
+                }
+            }
+
+        private:
+            int rank_;
+            size_type i_;
+            size_type j_;
+            vectoriterator_type itv_;
+            subiterator_type it_;
+
+            friend class const_iterator2;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator2 begin2 () {
+            return find2 (0, 0, 0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator2 end2 () {
+            return find2 (0, 0, size2_);
+        }
+
+        // Reverse iterators
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rbegin1 () const {
+            return const_reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crbegin1 () const {
+            return rbegin1 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 rend1 () const {
+            return const_reverse_iterator1 (begin1 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator1 crend1 () const {
+            return rend1 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rbegin1 () {
+            return reverse_iterator1 (end1 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator1 rend1 () {
+            return reverse_iterator1 (begin1 ());
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rbegin2 () const {
+            return const_reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crbegin2 () const {
+            return rbegin2 ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 rend2 () const {
+            return const_reverse_iterator2 (begin2 ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator2 crend2 () const {
+            return rend2 ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rbegin2 () {
+            return reverse_iterator2 (end2 ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator2 rend2 () {
+            return reverse_iterator2 (begin2 ());
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+        
+            // we need to copy to a collection_size_type to get a portable
+            // and efficient serialization
+            serialization::collection_size_type s1 (size1_);
+            serialization::collection_size_type s2 (size2_);
+          
+            // serialize the sizes
+            ar & serialization::make_nvp("size1",s1)
+               & serialization::make_nvp("size2",s2);
+
+            // copy the values back if loading
+            if (Archive::is_loading::value) {
+                size1_ = s1;
+                size2_ = s2;
+            }
+
+            ar & serialization::make_nvp("data", data_);
+
+            storage_invariants();
+        }
+
+    private:
+        void storage_invariants () const
+        {
+            BOOST_UBLAS_CHECK (layout_type::size_M (size1_, size2_) + 1 == data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());
+
+        }
+        size_type size1_;
+        size_type size2_;
+        array_type data_;
+        static const value_type zero_;
+    };
+
+    template<class T, class L, class A>
+    const typename generalized_vector_of_vector<T, L, A>::value_type generalized_vector_of_vector<T, L, A>::zero_ = value_type/*zero*/();
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/vector_proxy.hpp b/include/boost/numeric/ublas/vector_proxy.hpp
new file mode 100644
index 0000000..e3df99a
--- /dev/null
+++ b/include/boost/numeric/ublas/vector_proxy.hpp
@@ -0,0 +1,1697 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_VECTOR_PROXY_
+#define _BOOST_UBLAS_VECTOR_PROXY_
+
+#include <boost/numeric/ublas/vector_expression.hpp>
+#include <boost/numeric/ublas/detail/vector_assign.hpp>
+#include <boost/numeric/ublas/detail/temporary.hpp>
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+
+    /** \brief A vector referencing a continuous subvector of elements of vector \c v containing all elements specified by \c range.
+     *
+     * A vector range can be used as a normal vector in any expression. 
+     * If the specified range falls outside that of the index range of the vector, then
+     * the \c vector_range is not a well formed \i Vector \i Expression and access to an 
+     * element outside of index range of the vector is \b undefined.
+     *
+     * \tparam V the type of vector referenced (for example \c vector<double>)
+     */
+    template<class V>
+    class vector_range:
+        public vector_expression<vector_range<V> > {
+
+        typedef vector_range<V> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<self_type>::operator ();
+#endif
+        typedef const V const_vector_type;
+        typedef V vector_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::difference_type difference_type;
+        typedef typename V::value_type value_type;
+        typedef typename V::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<V>,
+                                          typename V::const_reference,
+                                          typename V::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<V>,
+                                          typename V::const_closure_type,
+                                          typename V::closure_type>::type vector_closure_type;
+        typedef basic_range<size_type, difference_type> range_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename V::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        vector_range (vector_type &data, const range_type &r):
+            data_ (data), r_ (r.preprocess (data.size ())) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (r_.start () <= data_.size () &&
+            //                   r_.start () + r_.size () <= data_.size (), bad_index ());
+        }
+        BOOST_UBLAS_INLINE
+        vector_range (const vector_closure_type &data, const range_type &r, bool):
+            data_ (data), r_ (r.preprocess (data.size ())) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (r_.start () <= data_.size () &&
+            //                    r_.start () + r_.size () <= data_.size (), bad_index ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type start () const {
+            return r_.start ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return r_.size ();
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const vector_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        vector_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return data_ (r_ (i));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            return data_ (r_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) const {
+            return data_ (r_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+#endif
+
+        // ISSUE can this be done in free project function?
+        // Although a const function can create a non-const proxy to a non-const object
+        // Critical is that vector_type and data_ (vector_closure_type) are const correct
+        BOOST_UBLAS_INLINE
+        vector_range<vector_type> project (const range_type &r) const {
+            return vector_range<vector_type> (data_, r_.compose (r.preprocess (data_.size ())), false);
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        vector_range &operator = (const vector_range &vr) {
+            // ISSUE need a temporary, proxy can be overlaping alias
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vr));
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        vector_range &assign_temporary (vector_range &vr) {
+            // assign elements, proxied container remains the same
+            vector_assign<scalar_assign> (*this, vr);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_range &operator = (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_range &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_range &operator += (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_range &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_range &operator -= (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_range &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        vector_range &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        vector_range &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const vector_range &vr) const {
+            return (*this).data_.same_closure (vr.data_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const vector_range &vr) const {
+            return (*this).data_ == vr.data_ && r_ == vr.r_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (vector_range vr) {
+            if (this != &vr) {
+                BOOST_UBLAS_CHECK (size () == vr.size (), bad_size ());
+                // Sparse ranges may be nonconformant now.
+                // std::swap_ranges (begin (), end (), vr.begin ());
+                vector_swap<scalar_swap> (*this, vr);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (vector_range vr1, vector_range vr2) {
+            vr1.swap (vr2);
+        }
+
+        // Iterator types
+    private:
+        typedef typename V::const_iterator const_subiterator_type;
+        typedef typename boost::mpl::if_<boost::is_const<V>,
+                                          typename V::const_iterator,
+                                          typename V::iterator>::type subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator<vector_range<vector_type>,
+                                 typename subiterator_type::iterator_category> iterator;
+        typedef indexed_const_iterator<vector_range<vector_type>,
+                                       typename const_subiterator_type::iterator_category> const_iterator;
+#else
+        class const_iterator;
+        class iterator;
+#endif
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+            const_subiterator_type it (data_.find (start () + i));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator (*this, it.index ());
+#else
+            return const_iterator (*this, it);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator find (size_type i) {
+            subiterator_type it (data_.find (start () + i));
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator (*this, it.index ());
+#else
+            return iterator (*this, it);
+#endif
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<vector_range>,
+            public iterator_base_traits<typename const_subiterator_type::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename const_subiterator_type::difference_type difference_type;
+            typedef typename const_subiterator_type::value_type value_type;
+            typedef typename const_subiterator_type::reference reference;
+            typedef typename const_subiterator_type::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &vr, const const_subiterator_type &it):
+                container_const_reference<self_type> (vr), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index () - (*this) ().start ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator:
+            public container_reference<vector_range>,
+            public iterator_base_traits<typename subiterator_type::iterator_category>::template
+                        iterator_base<iterator, value_type>::type {
+        public:
+            typedef typename subiterator_type::difference_type difference_type;
+            typedef typename subiterator_type::value_type value_type;
+            typedef typename subiterator_type::reference reference;
+            typedef typename subiterator_type::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &vr, const subiterator_type &it):
+                container_reference<self_type> (vr), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return *it_;
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index () - (*this) ().start ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (size ());
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        vector_closure_type data_;
+        range_type r_;
+    };
+
+    // ------------------
+    // Simple Projections
+    // ------------------
+
+    /** \brief Return a \c vector_range on a specified vector, a start and stop index.
+     * Return a \c vector_range on a specified vector, a start and stop index. The resulting \c vector_range can be manipulated like a normal vector.
+     * If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
+     * Vector Expression and access to an element outside of index range of the vector is \b undefined.
+     */
+    template<class V>
+    BOOST_UBLAS_INLINE
+    vector_range<V> subrange (V &data, typename V::size_type start, typename V::size_type stop) {
+        typedef basic_range<typename V::size_type, typename V::difference_type> range_type;
+        return vector_range<V> (data, range_type (start, stop));
+    }
+
+    /** \brief Return a \c const \c vector_range on a specified vector, a start and stop index.
+     * Return a \c const \c vector_range on a specified vector, a start and stop index. The resulting \c const \c vector_range can be manipulated like a normal vector.
+     *If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
+     * Vector Expression and access to an element outside of index range of the vector is \b undefined.
+     */
+    template<class V>
+    BOOST_UBLAS_INLINE
+    vector_range<const V> subrange (const V &data, typename V::size_type start, typename V::size_type stop) {
+        typedef basic_range<typename V::size_type, typename V::difference_type> range_type;
+        return vector_range<const V> (data, range_type (start, stop));
+    }
+
+    // -------------------
+    // Generic Projections
+    // -------------------
+    
+    /** \brief Return a \c const \c vector_range on a specified vector and \c range
+     * Return a \c const \c vector_range on a specified vector and \c range. The resulting \c vector_range can be manipulated like a normal vector.
+     * If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
+     * Vector Expression and access to an element outside of index range of the vector is \b undefined.
+     */
+    template<class V>
+    BOOST_UBLAS_INLINE
+    vector_range<V> project (V &data, typename vector_range<V>::range_type const &r) {
+        return vector_range<V> (data, r);
+    }
+
+    /** \brief Return a \c vector_range on a specified vector and \c range
+     * Return a \c vector_range on a specified vector and \c range. The resulting \c vector_range can be manipulated like a normal vector.
+     * If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
+     * Vector Expression and access to an element outside of index range of the vector is \b undefined.
+     */
+    template<class V>
+    BOOST_UBLAS_INLINE
+    const vector_range<const V> project (const V &data, typename vector_range<V>::range_type const &r) {
+        // ISSUE was: return vector_range<V> (const_cast<V &> (data), r);
+        return vector_range<const V> (data, r);
+   }
+
+    /** \brief Return a \c const \c vector_range on a specified vector and const \c range
+     * Return a \c const \c vector_range on a specified vector and const \c range. The resulting \c vector_range can be manipulated like a normal vector.
+     * If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
+     * Vector Expression and access to an element outside of index range of the vector is \b undefined.
+     */
+    template<class V>
+    BOOST_UBLAS_INLINE
+    vector_range<V> project (vector_range<V> &data, const typename vector_range<V>::range_type &r) {
+        return data.project (r);
+    }
+
+    /** \brief Return a \c vector_range on a specified vector and const \c range
+     * Return a \c vector_range on a specified vector and const \c range. The resulting \c vector_range can be manipulated like a normal vector.
+     * If the specified range falls outside that of of the index range of the vector, then the resulting \c vector_range is not a well formed
+     * Vector Expression and access to an element outside of index range of the vector is \b undefined.
+     */
+    template<class V>
+    BOOST_UBLAS_INLINE
+    const vector_range<V> project (const vector_range<V> &data, const typename vector_range<V>::range_type &r) {
+        return data.project (r);
+    }
+
+    // Specialization of temporary_traits
+    template <class V>
+    struct vector_temporary_traits< vector_range<V> >
+    : vector_temporary_traits< V > {} ;
+    template <class V>
+    struct vector_temporary_traits< const vector_range<V> >
+    : vector_temporary_traits< V > {} ;
+
+
+    /** \brief A vector referencing a non continuous subvector of elements of vector v containing all elements specified by \c slice.
+     *
+     * A vector slice can be used as a normal vector in any expression.
+     * If the specified slice falls outside that of the index slice of the vector, then
+     * the \c vector_slice is not a well formed \i Vector \i Expression and access to an 
+     * element outside of index slice of the vector is \b undefined.
+     *
+     * A slice is a generalization of a range. In a range going from \f$a\f$ to \f$b\f$, 
+     * all elements belong to the range. In a slice, a \i \f$step\f$ can be specified meaning to
+     * take one element over \f$step\f$ in the range specified from \f$a\f$ to \f$b\f$.
+     * Obviously, a slice with a \f$step\f$ of 1 is equivalent to a range.
+     *
+     * \tparam V the type of vector referenced (for example \c vector<double>)
+     */
+    template<class V>
+    class vector_slice:
+        public vector_expression<vector_slice<V> > {
+
+        typedef vector_slice<V> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<self_type>::operator ();
+#endif
+        typedef const V const_vector_type;
+        typedef V vector_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::difference_type difference_type;
+        typedef typename V::value_type value_type;
+        typedef typename V::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<V>,
+                                          typename V::const_reference,
+                                          typename V::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<V>,
+                                          typename V::const_closure_type,
+                                          typename V::closure_type>::type vector_closure_type;
+        typedef basic_range<size_type, difference_type> range_type;
+        typedef basic_slice<size_type, difference_type> slice_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename V::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        vector_slice (vector_type &data, const slice_type &s):
+            data_ (data), s_ (s.preprocess (data.size ())) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (s_.start () <= data_.size () &&
+            //                    s_.start () + s_.stride () * (s_.size () - (s_.size () > 0)) <= data_.size (), bad_index ());
+        }
+        BOOST_UBLAS_INLINE
+        vector_slice (const vector_closure_type &data, const slice_type &s, int):
+            data_ (data), s_ (s.preprocess (data.size ())) {
+            // Early checking of preconditions here.
+            // BOOST_UBLAS_CHECK (s_.start () <= data_.size () &&
+            //                    s_.start () + s_.stride () * (s_.size () - (s_.size () > 0)) <= data_.size (), bad_index ());
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type start () const {
+            return s_.start ();
+        }
+        BOOST_UBLAS_INLINE
+        difference_type stride () const {
+            return s_.stride ();
+        }
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return s_.size ();
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const vector_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        vector_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return data_ (s_ (i));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            return data_ (s_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) const {
+            return data_ (s_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+#endif
+
+        // ISSUE can this be done in free project function?
+        // Although a const function can create a non-const proxy to a non-const object
+        // Critical is that vector_type and data_ (vector_closure_type) are const correct
+        BOOST_UBLAS_INLINE
+        vector_slice<vector_type> project (const range_type &r) const {
+            return vector_slice<vector_type>  (data_, s_.compose (r.preprocess (data_.size ())), false);
+        }
+        BOOST_UBLAS_INLINE
+        vector_slice<vector_type> project (const slice_type &s) const {
+            return vector_slice<vector_type>  (data_, s_.compose (s.preprocess (data_.size ())), false);
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        vector_slice &operator = (const vector_slice &vs) {
+            // ISSUE need a temporary, proxy can be overlaping alias
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vs));
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        vector_slice &assign_temporary (vector_slice &vs) {
+            // assign elements, proxied container remains the same
+            vector_assign<scalar_assign> (*this, vs);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_slice &operator = (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_slice &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_slice &operator += (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_slice &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_slice &operator -= (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_slice &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        vector_slice &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        vector_slice &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const vector_slice &vr) const {
+            return (*this).data_.same_closure (vr.data_);
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const vector_slice &vs) const {
+            return (*this).data_ == vs.data_ && s_ == vs.s_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (vector_slice vs) {
+            if (this != &vs) {
+                BOOST_UBLAS_CHECK (size () == vs.size (), bad_size ());
+                // Sparse ranges may be nonconformant now.
+                // std::swap_ranges (begin (), end (), vs.begin ());
+                vector_swap<scalar_swap> (*this, vs);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (vector_slice vs1, vector_slice vs2) {
+            vs1.swap (vs2);
+        }
+
+        // Iterator types
+    private:
+        // Use slice as an index - FIXME this fails for packed assignment
+        typedef typename slice_type::const_iterator const_subiterator_type;
+        typedef typename slice_type::const_iterator subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator<vector_slice<vector_type>,
+                                 typename vector_type::iterator::iterator_category> iterator;
+        typedef indexed_const_iterator<vector_slice<vector_type>,
+                                       typename vector_type::const_iterator::iterator_category> const_iterator;
+#else
+        class const_iterator;
+        class iterator;
+#endif
+
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator (*this, i);
+#else
+            return const_iterator (*this, s_.begin () + i);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator find (size_type i) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator (*this, i);
+#else
+            return iterator (*this, s_.begin () + i);
+#endif
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<vector_slice>,
+            public iterator_base_traits<typename V::const_iterator::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename V::const_iterator::difference_type difference_type;
+            typedef typename V::const_iterator::value_type value_type;
+            typedef typename V::const_reference reference;    //FIXME due to indexing access
+            typedef typename V::const_iterator::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &vs, const const_subiterator_type &it):
+                container_const_reference<self_type> (vs), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                // FIXME replace find with at_element
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return (*this) ().data_ (*it_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator:
+            public container_reference<vector_slice>,
+            public iterator_base_traits<typename V::iterator::iterator_category>::template
+                        iterator_base<iterator, value_type>::type {
+        public:
+            typedef typename V::iterator::difference_type difference_type;
+            typedef typename V::iterator::value_type value_type;
+            typedef typename V::reference reference;    //FIXME due to indexing access
+            typedef typename V::iterator::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &vs, const subiterator_type &it):
+                container_reference<self_type> (vs), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                // FIXME replace find with at_element
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return (*this) ().data_ (*it_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (size ());
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        vector_closure_type data_;
+        slice_type s_;
+    };
+
+    // Simple Projections
+    template<class V>
+    BOOST_UBLAS_INLINE
+    vector_slice<V> subslice (V &data, typename V::size_type start, typename V::difference_type stride, typename V::size_type size) {
+        typedef basic_slice<typename V::size_type, typename V::difference_type> slice_type;
+        return vector_slice<V> (data, slice_type (start, stride, size));
+    }
+    template<class V>
+    BOOST_UBLAS_INLINE
+    vector_slice<const V> subslice (const V &data, typename V::size_type start, typename V::difference_type stride, typename V::size_type size)  {
+        typedef basic_slice<typename V::size_type, typename V::difference_type> slice_type;
+        return vector_slice<const V> (data, slice_type (start, stride, size));
+    }
+
+    // Generic Projections
+    template<class V>
+    BOOST_UBLAS_INLINE
+    vector_slice<V> project (V &data, const typename vector_slice<V>::slice_type &s) {
+        return vector_slice<V> (data, s);
+    }
+    template<class V>
+    BOOST_UBLAS_INLINE
+    const vector_slice<const V> project (const V &data, const typename vector_slice<V>::slice_type &s) {
+        // ISSUE was: return vector_slice<V> (const_cast<V &> (data), s);
+        return vector_slice<const V> (data, s);
+    }
+    template<class V>
+    BOOST_UBLAS_INLINE
+    vector_slice<V> project (vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
+        return data.project (s);
+    }
+    template<class V>
+    BOOST_UBLAS_INLINE
+    const vector_slice<V> project (const vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
+        return data.project (s);
+    }
+    // ISSUE in the following two functions it would be logical to use vector_slice<V>::range_type but this confuses VC7.1 and 8.0
+    template<class V>
+    BOOST_UBLAS_INLINE
+    vector_slice<V> project (vector_slice<V> &data, const typename vector_range<V>::range_type &r) {
+        return data.project (r);
+    }
+    template<class V>
+    BOOST_UBLAS_INLINE
+    const vector_slice<V> project (const vector_slice<V> &data, const typename vector_range<V>::range_type &r) {
+        return data.project (r);
+    }
+
+    // Specialization of temporary_traits
+    template <class V>
+    struct vector_temporary_traits< vector_slice<V> >
+    : vector_temporary_traits< V > {} ;
+    template <class V>
+    struct vector_temporary_traits< const vector_slice<V> >
+    : vector_temporary_traits< V > {} ;
+
+
+    // Vector based indirection class
+    // Contributed by Toon Knapen.
+    // Extended and optimized by Kresimir Fresl.
+
+    /** \brief A vector referencing a non continuous subvector of elements given another vector of indices.
+     *
+     * It is the most general version of any subvectors because it uses another vector of indices to reference
+     * the subvector. 
+     *
+     * The vector of indices can be of any type with the restriction that its elements must be
+     * type-compatible with the size_type \c of the container. In practice, the following are good candidates:
+     * - \c boost::numeric::ublas::indirect_array<A> where \c A can be \c int, \c size_t, \c long, etc...
+     * - \c std::vector<A> where \c A can \c int, \c size_t, \c long, etc...
+     * - \c boost::numeric::ublas::vector<int> can work too (\c int can be replaced by another integer type)
+     * - etc...
+     *
+     * An indirect vector can be used as a normal vector in any expression. If the specified indirect vector 
+     * falls outside that of the indices of the vector, then the \c vector_indirect is not a well formed 
+     * \i Vector \i Expression and access to an element outside of indices of the vector is \b undefined.
+     *
+     * \tparam V the type of vector referenced (for example \c vector<double>)
+     * \tparam IA the type of index vector. Default is \c ublas::indirect_array<>
+     */
+    template<class V, class IA>
+    class vector_indirect:
+        public vector_expression<vector_indirect<V, IA> > {
+
+        typedef vector_indirect<V, IA> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_expression<self_type>::operator ();
+#endif
+        typedef const V const_vector_type;
+        typedef V vector_type;
+        typedef const IA const_indirect_array_type;
+        typedef IA indirect_array_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::difference_type difference_type;
+        typedef typename V::value_type value_type;
+        typedef typename V::const_reference const_reference;
+        typedef typename boost::mpl::if_<boost::is_const<V>,
+                                          typename V::const_reference,
+                                          typename V::reference>::type reference;
+        typedef typename boost::mpl::if_<boost::is_const<V>,
+                                          typename V::const_closure_type,
+                                          typename V::closure_type>::type vector_closure_type;
+        typedef basic_range<size_type, difference_type> range_type;
+        typedef basic_slice<size_type, difference_type> slice_type;
+        typedef const self_type const_closure_type;
+        typedef self_type closure_type;
+        typedef typename storage_restrict_traits<typename V::storage_category,
+                                                 dense_proxy_tag>::storage_category storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        vector_indirect (vector_type &data, size_type size):
+            data_ (data), ia_ (size) {}
+        BOOST_UBLAS_INLINE
+        vector_indirect (vector_type &data, const indirect_array_type &ia):
+            data_ (data), ia_ (ia.preprocess (data.size ())) {}
+        BOOST_UBLAS_INLINE
+        vector_indirect (const vector_closure_type &data, const indirect_array_type &ia, int):
+            data_ (data), ia_ (ia.preprocess (data.size ())) {}
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return ia_.size ();
+        }
+        BOOST_UBLAS_INLINE
+        const_indirect_array_type &indirect () const {
+            return ia_;
+        }
+        BOOST_UBLAS_INLINE
+        indirect_array_type &indirect () {
+            return ia_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const vector_closure_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        vector_closure_type &data () {
+            return data_;
+        }
+
+        // Element access
+#ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            return data_ (ia_ (i));
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+            return data_ (ia_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+#else
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) const {
+            return data_ (ia_ (i));
+        }
+
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+#endif
+
+        // ISSUE can this be done in free project function?
+        // Although a const function can create a non-const proxy to a non-const object
+        // Critical is that vector_type and data_ (vector_closure_type) are const correct
+        BOOST_UBLAS_INLINE
+        vector_indirect<vector_type, indirect_array_type> project (const range_type &r) const {
+            return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (r.preprocess (data_.size ())), 0);
+        }
+        BOOST_UBLAS_INLINE
+        vector_indirect<vector_type, indirect_array_type> project (const slice_type &s) const {
+            return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (s.preprocess (data_.size ())), 0);
+        }
+        BOOST_UBLAS_INLINE
+        vector_indirect<vector_type, indirect_array_type> project (const indirect_array_type &ia) const {
+            return vector_indirect<vector_type, indirect_array_type> (data_, ia_.compose (ia.preprocess (data_.size ())), 0);
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        vector_indirect &operator = (const vector_indirect &vi) {
+            // ISSUE need a temporary, proxy can be overlaping alias
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (vi));
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        vector_indirect &assign_temporary (vector_indirect &vi) {
+            // assign elements, proxied container remains the same
+            vector_assign<scalar_assign> (*this, vi);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_indirect &operator = (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_indirect &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_indirect &operator += (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this + ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_indirect &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_indirect &operator -= (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, typename vector_temporary_traits<V>::type (*this - ae));
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        vector_indirect &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        vector_indirect &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        vector_indirect &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Closure comparison
+        BOOST_UBLAS_INLINE
+        bool same_closure (const vector_indirect &/*vr*/) const {
+            return true;
+        }
+
+        // Comparison
+        BOOST_UBLAS_INLINE
+        bool operator == (const vector_indirect &vi) const {
+            return (*this).data_ == vi.data_ && ia_ == vi.ia_;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (vector_indirect vi) {
+            if (this != &vi) {
+                BOOST_UBLAS_CHECK (size () == vi.size (), bad_size ());
+                // Sparse ranges may be nonconformant now.
+                // std::swap_ranges (begin (), end (), vi.begin ());
+                vector_swap<scalar_swap> (*this, vi);
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (vector_indirect vi1, vector_indirect vi2) {
+            vi1.swap (vi2);
+        }
+
+        // Iterator types
+    private:
+        // Use indirect array as an index - FIXME this fails for packed assignment
+        typedef typename IA::const_iterator const_subiterator_type;
+        typedef typename IA::const_iterator subiterator_type;
+
+    public:
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        typedef indexed_iterator<vector_indirect<vector_type, indirect_array_type>,
+                                 typename vector_type::iterator::iterator_category> iterator;
+        typedef indexed_const_iterator<vector_indirect<vector_type, indirect_array_type>,
+                                       typename vector_type::const_iterator::iterator_category> const_iterator;
+#else
+        class const_iterator;
+        class iterator;
+#endif
+        // Element lookup
+        BOOST_UBLAS_INLINE
+        const_iterator find (size_type i) const {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return const_iterator (*this, i);
+#else
+            return const_iterator (*this, ia_.begin () + i);
+#endif
+        }
+        BOOST_UBLAS_INLINE
+        iterator find (size_type i) {
+#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
+            return iterator (*this, i);
+#else
+            return iterator (*this, ia_.begin () + i);
+#endif
+        }
+
+        // Iterators simply are indices.
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class const_iterator:
+            public container_const_reference<vector_indirect>,
+            public iterator_base_traits<typename V::const_iterator::iterator_category>::template
+                        iterator_base<const_iterator, value_type>::type {
+        public:
+            typedef typename V::const_iterator::difference_type difference_type;
+            typedef typename V::const_iterator::value_type value_type;
+            typedef typename V::const_reference reference;    //FIXME due to indexing access
+            typedef typename V::const_iterator::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &vi, const const_subiterator_type &it):
+                container_const_reference<self_type> (vi), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                // FIXME replace find with at_element
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return (*this) ().data_ (*it_);
+            }
+            BOOST_UBLAS_INLINE
+            const_reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
+        class iterator:
+            public container_reference<vector_indirect>,
+            public iterator_base_traits<typename V::iterator::iterator_category>::template
+                        iterator_base<iterator, value_type>::type {
+        public:
+            typedef typename V::iterator::difference_type difference_type;
+            typedef typename V::iterator::value_type value_type;
+            typedef typename V::reference reference;    //FIXME due to indexing access
+            typedef typename V::iterator::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &vi, const subiterator_type &it):
+                container_reference<self_type> (vi), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator += (difference_type n) {
+                it_ += n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -= (difference_type n) {
+                it_ -= n;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            difference_type operator - (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ - it.it_;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                // FIXME replace find with at_element
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return (*this) ().data_ (*it_);
+            }
+            BOOST_UBLAS_INLINE
+            reference operator [] (difference_type n) const {
+                return *(*this + n);
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                return it_.index ();
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ == it.it_;
+            }
+            BOOST_UBLAS_INLINE
+            bool operator < (const iterator &it) const {
+                BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
+                return it_ < it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator;
+        };
+#endif
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (size ());
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+    private:
+        vector_closure_type data_;
+        indirect_array_type ia_;
+    };
+
+    // Projections
+    template<class V, class A>
+    BOOST_UBLAS_INLINE
+    vector_indirect<V, indirect_array<A> > project (V &data, const indirect_array<A> &ia) {
+        return vector_indirect<V, indirect_array<A> > (data, ia);
+    }
+    template<class V, class A>
+    BOOST_UBLAS_INLINE
+    const vector_indirect<const V, indirect_array<A> > project (const V &data, const indirect_array<A> &ia) {
+        // ISSUE was: return vector_indirect<V, indirect_array<A> > (const_cast<V &> (data), ia)
+        return vector_indirect<const V, indirect_array<A> > (data, ia);
+    }
+    template<class V, class IA>
+    BOOST_UBLAS_INLINE
+    vector_indirect<V, IA> project (vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::range_type &r) {
+        return data.project (r);
+    }
+    template<class V, class IA>
+    BOOST_UBLAS_INLINE
+    const vector_indirect<V, IA> project (const vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::range_type &r) {
+        return data.project (r);
+    }
+    template<class V, class IA>
+    BOOST_UBLAS_INLINE
+    vector_indirect<V, IA> project (vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::slice_type &s) {
+        return data.project (s);
+    }
+    template<class V, class IA>
+    BOOST_UBLAS_INLINE
+    const vector_indirect<V, IA> project (const vector_indirect<V, IA> &data, const typename vector_indirect<V, IA>::slice_type &s) {
+        return data.project (s);
+    }
+    template<class V, class A>
+    BOOST_UBLAS_INLINE
+    vector_indirect<V, indirect_array<A> > project (vector_indirect<V, indirect_array<A> > &data, const indirect_array<A> &ia) {
+        return data.project (ia);
+    }
+    template<class V, class A>
+    BOOST_UBLAS_INLINE
+    const vector_indirect<V, indirect_array<A> > project (const vector_indirect<V, indirect_array<A> > &data, const indirect_array<A> &ia) {
+        return data.project (ia);
+    }
+
+    // Specialization of temporary_traits
+    template <class V>
+    struct vector_temporary_traits< vector_indirect<V> >
+    : vector_temporary_traits< V > {} ;
+    template <class V>
+    struct vector_temporary_traits< const vector_indirect<V> >
+    : vector_temporary_traits< V > {} ;
+
+}}}
+
+#endif
diff --git a/include/boost/numeric/ublas/vector_sparse.hpp b/include/boost/numeric/ublas/vector_sparse.hpp
new file mode 100644
index 0000000..07c64cb
--- /dev/null
+++ b/include/boost/numeric/ublas/vector_sparse.hpp
@@ -0,0 +1,2215 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef _BOOST_UBLAS_VECTOR_SPARSE_
+#define _BOOST_UBLAS_VECTOR_SPARSE_
+
+#include <boost/numeric/ublas/storage_sparse.hpp>
+#include <boost/numeric/ublas/vector_expression.hpp>
+#include <boost/numeric/ublas/detail/vector_assign.hpp>
+#if BOOST_UBLAS_TYPE_CHECK
+#include <boost/numeric/ublas/vector.hpp>
+#endif
+
+// Iterators based on ideas of Jeremy Siek
+
+namespace boost { namespace numeric { namespace ublas {
+
+#ifdef BOOST_UBLAS_STRICT_VECTOR_SPARSE
+
+    template<class V>
+    class sparse_vector_element:
+       public container_reference<V> {
+    public:
+        typedef V vector_type;
+        typedef typename V::size_type size_type;
+        typedef typename V::value_type value_type;
+        typedef const value_type &const_reference;
+        typedef value_type *pointer;
+
+    private:
+        // Proxied element operations
+        void get_d () const {
+            pointer p = (*this) ().find_element (i_);
+            if (p)
+                d_ = *p;
+            else
+                d_ = value_type/*zero*/();
+        }
+
+        void set (const value_type &s) const {
+            pointer p = (*this) ().find_element (i_);
+            if (!p)
+                (*this) ().insert_element (i_, s);
+            else
+                *p = s;
+        }
+
+    public:
+        // Construction and destruction
+        sparse_vector_element (vector_type &v, size_type i):
+            container_reference<vector_type> (v), i_ (i) {
+        }
+        BOOST_UBLAS_INLINE
+        sparse_vector_element (const sparse_vector_element &p):
+            container_reference<vector_type> (p), i_ (p.i_) {}
+        BOOST_UBLAS_INLINE
+        ~sparse_vector_element () {
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        sparse_vector_element &operator = (const sparse_vector_element &p) {
+            // Overide the implict copy assignment
+            p.get_d ();
+            set (p.d_);
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_vector_element &operator = (const D &d) {
+            set (d);
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_vector_element &operator += (const D &d) {
+            get_d ();
+            d_ += d;
+            set (d_);
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_vector_element &operator -= (const D &d) {
+            get_d ();
+            d_ -= d;
+            set (d_);
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_vector_element &operator *= (const D &d) {
+            get_d ();
+            d_ *= d;
+            set (d_);
+            return *this;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        sparse_vector_element &operator /= (const D &d) {
+            get_d ();
+            d_ /= d;
+            set (d_);
+            return *this;
+        }
+
+        // Comparison
+        template<class D>
+        BOOST_UBLAS_INLINE
+        bool operator == (const D &d) const {
+            get_d ();
+            return d_ == d;
+        }
+        template<class D>
+        BOOST_UBLAS_INLINE
+        bool operator != (const D &d) const {
+            get_d ();
+            return d_ != d;
+        }
+
+        // Conversion - weak link in proxy as d_ is not a perfect alias for the element
+        BOOST_UBLAS_INLINE
+        operator const_reference () const {
+            get_d ();
+            return d_;
+        }
+
+        // Conversion to reference - may be invalidated
+        BOOST_UBLAS_INLINE
+        value_type& ref () const {
+            const pointer p = (*this) ().find_element (i_);
+            if (!p)
+                return (*this) ().insert_element (i_, value_type/*zero*/());
+            else
+                return *p;
+        }
+
+    private:
+        size_type i_;
+        mutable value_type d_;
+    };
+
+    /*
+     * Generalise explicit reference access
+     */
+    namespace detail {
+        template <class R>
+        struct element_reference {
+            typedef R& reference;
+            static reference get_reference (reference r)
+            {
+                return r;
+            }
+        };
+        template <class V>
+        struct element_reference<sparse_vector_element<V> > {
+            typedef typename V::value_type& reference;
+            static reference get_reference (const sparse_vector_element<V>& sve)
+            {
+                return sve.ref ();
+            }
+        };
+    }
+    template <class VER>
+    typename detail::element_reference<VER>::reference ref (VER& ver) {
+        return detail::element_reference<VER>::get_reference (ver);
+    }
+    template <class VER>
+    typename detail::element_reference<VER>::reference ref (const VER& ver) {
+        return detail::element_reference<VER>::get_reference (ver);
+    }
+
+
+    template<class V>
+    struct type_traits<sparse_vector_element<V> > {
+        typedef typename V::value_type element_type;
+        typedef type_traits<sparse_vector_element<V> > self_type;
+        typedef typename type_traits<element_type>::value_type value_type;
+        typedef typename type_traits<element_type>::const_reference const_reference;
+        typedef sparse_vector_element<V> reference;
+        typedef typename type_traits<element_type>::real_type real_type;
+        typedef typename type_traits<element_type>::precision_type precision_type;
+
+        static const unsigned plus_complexity = type_traits<element_type>::plus_complexity;
+        static const unsigned multiplies_complexity = type_traits<element_type>::multiplies_complexity;
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type real (const_reference t) {
+            return type_traits<element_type>::real (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type imag (const_reference t) {
+            return type_traits<element_type>::imag (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        value_type conj (const_reference t) {
+            return type_traits<element_type>::conj (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type type_abs (const_reference t) {
+            return type_traits<element_type>::type_abs (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        value_type type_sqrt (const_reference t) {
+            return type_traits<element_type>::type_sqrt (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_1 (const_reference t) {
+            return type_traits<element_type>::norm_1 (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_2 (const_reference t) {
+            return type_traits<element_type>::norm_2 (t);
+        }
+        static
+        BOOST_UBLAS_INLINE
+        real_type norm_inf (const_reference t) {
+            return type_traits<element_type>::norm_inf (t);
+        }
+
+        static
+        BOOST_UBLAS_INLINE
+        bool equals (const_reference t1, const_reference t2) {
+            return type_traits<element_type>::equals (t1, t2);
+        }
+    };
+
+    template<class V1, class T2>
+    struct promote_traits<sparse_vector_element<V1>, T2> {
+        typedef typename promote_traits<typename sparse_vector_element<V1>::value_type, T2>::promote_type promote_type;
+    };
+    template<class T1, class V2>
+    struct promote_traits<T1, sparse_vector_element<V2> > {
+        typedef typename promote_traits<T1, typename sparse_vector_element<V2>::value_type>::promote_type promote_type;
+    };
+    template<class V1, class V2>
+    struct promote_traits<sparse_vector_element<V1>, sparse_vector_element<V2> > {
+        typedef typename promote_traits<typename sparse_vector_element<V1>::value_type,
+                                        typename sparse_vector_element<V2>::value_type>::promote_type promote_type;
+    };
+
+#endif
+
+
+    /** \brief Index map based sparse vector
+     *
+     * A sparse vector of values of type T of variable size. The sparse storage type A can be 
+     * \c std::map<size_t, T> or \c map_array<size_t, T>. This means that only non-zero elements
+     * are effectively stored.
+     *
+     * For a \f$n\f$-dimensional sparse vector,  and 0 <= i < n the non-zero elements \f$v_i\f$ 
+     * are mapped to consecutive elements of the associative container, i.e. for elements 
+     * \f$k = v_{i_1}\f$ and \f$k + 1 = v_{i_2}\f$ of the container, holds \f$i_1 < i_2\f$.
+     *
+     * Supported parameters for the adapted array are \c map_array<std::size_t, T> and 
+     * \c map_std<std::size_t, T>. The latter is equivalent to \c std::map<std::size_t, T>.
+     *
+     * \tparam T the type of object stored in the vector (like double, float, complex, etc...)
+     * \tparam A the type of Storage array
+     */
+    template<class T, class A>
+    class mapped_vector:
+        public vector_container<mapped_vector<T, A> > {
+
+        typedef T &true_reference;
+        typedef T *pointer;
+        typedef const T *const_pointer;
+        typedef mapped_vector<T, A> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_container<self_type>::operator ();
+#endif
+        typedef typename A::size_type size_type;
+        typedef typename A::difference_type difference_type;
+        typedef T value_type;
+        typedef A array_type;
+        typedef const value_type &const_reference;
+#ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE
+        typedef typename detail::map_traits<A,T>::reference reference;
+#else
+        typedef sparse_vector_element<self_type> reference;
+#endif
+        typedef const vector_reference<const self_type> const_closure_type;
+        typedef vector_reference<self_type> closure_type;
+        typedef self_type vector_temporary_type;
+        typedef sparse_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        mapped_vector ():
+            vector_container<self_type> (),
+            size_ (0), data_ () {}
+        BOOST_UBLAS_INLINE
+        mapped_vector (size_type size, size_type non_zeros = 0):
+            vector_container<self_type> (),
+            size_ (size), data_ () {
+            detail::map_reserve (data(), restrict_capacity (non_zeros));
+        }
+        BOOST_UBLAS_INLINE
+        mapped_vector (const mapped_vector &v):
+            vector_container<self_type> (),
+            size_ (v.size_), data_ (v.data_) {}
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector (const vector_expression<AE> &ae, size_type non_zeros = 0):
+            vector_container<self_type> (),
+            size_ (ae ().size ()), data_ () {
+            detail::map_reserve (data(), restrict_capacity (non_zeros));
+            vector_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return size_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz_capacity () const {
+            return detail::map_capacity (data ());
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz () const {
+            return data (). size ();
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        const array_type &data () const {
+            return data_;
+        }
+        BOOST_UBLAS_INLINE
+        array_type &data () {
+            return data_;
+        }
+
+        // Resizing
+    private:
+        BOOST_UBLAS_INLINE
+        size_type restrict_capacity (size_type non_zeros) const {
+            non_zeros = (std::min) (non_zeros, size_);
+            return non_zeros;
+        }
+    public:
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, bool preserve = true) {
+            size_ = size;
+            if (preserve) {
+                data ().erase (data ().lower_bound(size_), data ().end());
+            }
+            else {
+                data ().clear ();
+            }
+        }
+
+        // Reserving
+        BOOST_UBLAS_INLINE
+        void reserve (size_type non_zeros = 0, bool preserve = true) {
+            detail::map_reserve (data (), restrict_capacity (non_zeros));
+        }
+
+        // Element support
+        BOOST_UBLAS_INLINE
+        pointer find_element (size_type i) {
+            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
+        }
+        BOOST_UBLAS_INLINE
+        const_pointer find_element (size_type i) const {
+            const_subiterator_type it (data ().find (i));
+            if (it == data ().end ())
+                return 0;
+            BOOST_UBLAS_CHECK ((*it).first == i, internal_logic ());   // broken map
+            return &(*it).second;
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            const_subiterator_type it (data ().find (i));
+            if (it == data ().end ())
+                return zero_;
+            BOOST_UBLAS_CHECK ((*it).first == i, internal_logic ());   // broken map
+            return (*it).second;
+        }
+        BOOST_UBLAS_INLINE
+        true_reference ref (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            std::pair<subiterator_type, bool> ii (data ().insert (typename array_type::value_type (i, value_type/*zero*/())));
+            BOOST_UBLAS_CHECK ((ii.first)->first == i, internal_logic ());   // broken map
+            return (ii.first)->second;
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+#ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE
+            return ref (i);
+#else
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return reference (*this, i);
+#endif
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, const_reference t) {
+            std::pair<subiterator_type, bool> ii = data ().insert (typename array_type::value_type (i, t));
+            BOOST_UBLAS_CHECK (ii.second, bad_index ());        // duplicate element
+            BOOST_UBLAS_CHECK ((ii.first)->first == i, internal_logic ());   // broken map
+            if (!ii.second)     // existing element
+                (ii.first)->second = t;
+            return (ii.first)->second;
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i) {
+            subiterator_type it = data ().find (i);
+            if (it == data ().end ())
+                return;
+            data ().erase (it);
+        }
+
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            data ().clear ();
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        mapped_vector &operator = (const mapped_vector &v) {
+            if (this != &v) {
+                size_ = v.size_;
+                data () = v.data ();
+            }
+            return *this;
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        mapped_vector &operator = (const vector_container<C> &v) {
+            resize (v ().size (), false);
+            assign (v);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        mapped_vector &assign_temporary (mapped_vector &v) {
+            swap (v);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector &operator = (const vector_expression<AE> &ae) {
+            self_type temporary (ae, detail::map_capacity (data()));
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+
+        // Computed assignment
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector &operator += (const vector_expression<AE> &ae) {
+            self_type temporary (*this + ae, detail::map_capacity (data()));
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        mapped_vector &operator += (const vector_container<C> &v) {
+            plus_assign (v);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector &operator -= (const vector_expression<AE> &ae) {
+            self_type temporary (*this - ae, detail::map_capacity (data()));
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        mapped_vector &operator -= (const vector_container<C> &v) {
+            minus_assign (v);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        mapped_vector &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        mapped_vector &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        mapped_vector &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (mapped_vector &v) {
+            if (this != &v) {
+                std::swap (size_, v.size_);
+                data ().swap (v.data ());
+            }
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (mapped_vector &v1, mapped_vector &v2) {
+            v1.swap (v2);
+        }
+
+        // Iterator types
+    private:
+        // Use storage iterator
+        typedef typename A::const_iterator const_subiterator_type;
+        typedef typename A::iterator subiterator_type;
+
+        BOOST_UBLAS_INLINE
+        true_reference at_element (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            subiterator_type it (data ().find (i));
+            BOOST_UBLAS_CHECK (it != data ().end(), bad_index ());
+            BOOST_UBLAS_CHECK ((*it).first == i, internal_logic ());   // broken map
+            return it->second;
+        }
+
+    public:
+        class const_iterator;
+        class iterator;
+
+        // Element lookup
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+        const_iterator find (size_type i) const {
+            return const_iterator (*this, data ().lower_bound (i));
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+        iterator find (size_type i) {
+            return iterator (*this, data ().lower_bound (i));
+        }
+
+
+        class const_iterator:
+            public container_const_reference<mapped_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator, value_type> {
+        public:
+            typedef typename mapped_vector::value_type value_type;
+            typedef typename mapped_vector::difference_type difference_type;
+            typedef typename mapped_vector::const_reference reference;
+            typedef const typename mapped_vector::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &v, const const_subiterator_type &it):
+                container_const_reference<self_type> (v), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return (*it_).second;
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().end (), bad_index ());
+                BOOST_UBLAS_CHECK ((*it_).first < (*this) ().size (), bad_index ());
+                return (*it_).first;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return const_iterator (*this, data ().begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return const_iterator (*this, data ().end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        class iterator:
+            public container_reference<mapped_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator, value_type> {
+        public:
+            typedef typename mapped_vector::value_type value_type;
+            typedef typename mapped_vector::difference_type difference_type;
+            typedef typename mapped_vector::true_reference reference;
+            typedef typename mapped_vector::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &v, const subiterator_type &it):
+                container_reference<self_type> (v), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return (*it_).second;
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().end (), bad_index ());
+                BOOST_UBLAS_CHECK ((*it_).first < (*this) ().size (), bad_index ());
+                return (*it_).first;
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return iterator (*this, data ().begin ());
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return iterator (*this, data ().end ());
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+            serialization::collection_size_type s (size_);
+            ar & serialization::make_nvp("size",s);
+            if (Archive::is_loading::value) {
+                size_ = s;
+            }
+            ar & serialization::make_nvp("data", data_);
+        }
+
+    private:
+        size_type size_;
+        array_type data_;
+        static const value_type zero_;
+    };
+
+    template<class T, class A>
+    const typename mapped_vector<T, A>::value_type mapped_vector<T, A>::zero_ = value_type/*zero*/();
+
+
+    // Thanks to Kresimir Fresl for extending this to cover different index bases.
+    
+    /** \brief Compressed array based sparse vector
+     *
+     * a sparse vector of values of type T of variable size. The non zero values are stored as 
+     * two seperate arrays: an index array and a value array. The index array is always sorted 
+     * and there is at most one entry for each index. Inserting an element can be time consuming.
+     * If the vector contains a few zero entries, then it is better to have a normal vector.
+     * If the vector has a very high dimension with a few non-zero values, then this vector is
+     * very memory efficient (at the cost of a few more computations).
+     *
+     * For a \f$n\f$-dimensional compressed vector and \f$0 \leq i < n\f$ the non-zero elements 
+     * \f$v_i\f$ are mapped to consecutive elements of the index and value container, i.e. for 
+     * elements \f$k = v_{i_1}\f$ and \f$k + 1 = v_{i_2}\f$ of these containers holds \f$i_1 < i_2\f$.
+     *
+     * Supported parameters for the adapted array (indices and values) are \c unbounded_array<> ,
+     * \c bounded_array<> and \c std::vector<>.
+     *
+     * \tparam T the type of object stored in the vector (like double, float, complex, etc...)
+     * \tparam IB the index base of the compressed vector. Default is 0. Other supported value is 1
+     * \tparam IA the type of adapted array for indices. Default is \c unbounded_array<std::size_t>
+     * \tparam TA the type of adapted array for values. Default is unbounded_array<T>
+     */
+    template<class T, std::size_t IB, class IA, class TA>
+    class compressed_vector:
+        public vector_container<compressed_vector<T, IB, IA, TA> > {
+
+        typedef T &true_reference;
+        typedef T *pointer;
+        typedef const T *const_pointer;
+        typedef compressed_vector<T, IB, IA, TA> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_container<self_type>::operator ();
+#endif
+        // ISSUE require type consistency check
+        // is_convertable (IA::size_type, TA::size_type)
+        typedef typename IA::value_type size_type;
+        typedef typename IA::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+#ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE
+        typedef T &reference;
+#else
+        typedef sparse_vector_element<self_type> reference;
+#endif
+        typedef IA index_array_type;
+        typedef TA value_array_type;
+        typedef const vector_reference<const self_type> const_closure_type;
+        typedef vector_reference<self_type> closure_type;
+        typedef self_type vector_temporary_type;
+        typedef sparse_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        compressed_vector ():
+            vector_container<self_type> (),
+            size_ (0), capacity_ (restrict_capacity (0)), filled_ (0),
+            index_data_ (capacity_), value_data_ (capacity_) {
+            storage_invariants ();
+        }
+        explicit BOOST_UBLAS_INLINE
+        compressed_vector (size_type size, size_type non_zeros = 0):
+            vector_container<self_type> (),
+            size_ (size), capacity_ (restrict_capacity (non_zeros)), filled_ (0),
+            index_data_ (capacity_), value_data_ (capacity_) {
+        storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        compressed_vector (const compressed_vector &v):
+            vector_container<self_type> (),
+            size_ (v.size_), capacity_ (v.capacity_), filled_ (v.filled_),
+            index_data_ (v.index_data_), value_data_ (v.value_data_) {
+            storage_invariants ();
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_vector (const vector_expression<AE> &ae, size_type non_zeros = 0):
+            vector_container<self_type> (),
+            size_ (ae ().size ()), capacity_ (restrict_capacity (non_zeros)), filled_ (0),
+            index_data_ (capacity_), value_data_ (capacity_) {
+            storage_invariants ();
+            vector_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return size_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz_capacity () const {
+            return capacity_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz () const {
+            return filled_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        static size_type index_base () {
+            return IB;
+        }
+        BOOST_UBLAS_INLINE
+        typename index_array_type::size_type filled () const {
+            return filled_;
+        }
+        BOOST_UBLAS_INLINE
+        const index_array_type &index_data () const {
+            return index_data_;
+        }
+        BOOST_UBLAS_INLINE
+        const value_array_type &value_data () const {
+            return value_data_;
+        }
+        BOOST_UBLAS_INLINE
+        void set_filled (const typename index_array_type::size_type & filled) {
+            filled_ = filled;
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        index_array_type &index_data () {
+            return index_data_;
+        }
+        BOOST_UBLAS_INLINE
+        value_array_type &value_data () {
+            return value_data_;
+        }
+
+        // Resizing
+    private:
+        BOOST_UBLAS_INLINE
+        size_type restrict_capacity (size_type non_zeros) const {
+            non_zeros = (std::max) (non_zeros, size_type (1));
+            non_zeros = (std::min) (non_zeros, size_);
+            return non_zeros;
+        }
+    public:
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, bool preserve = true) {
+            size_ = size;
+            capacity_ = restrict_capacity (capacity_);
+            if (preserve) {
+                index_data_. resize (capacity_, size_type ());
+                value_data_. resize (capacity_, value_type ());
+                filled_ = (std::min) (capacity_, filled_);
+                while ((filled_ > 0) && (zero_based(index_data_[filled_ - 1]) >= size)) {
+                    --filled_;
+                }
+            }
+            else {
+                index_data_. resize (capacity_);
+                value_data_. resize (capacity_);
+                filled_ = 0;
+            }
+            storage_invariants ();
+        }
+
+        // Reserving
+        BOOST_UBLAS_INLINE
+        void reserve (size_type non_zeros, bool preserve = true) {
+            capacity_ = restrict_capacity (non_zeros);
+            if (preserve) {
+                index_data_. resize (capacity_, size_type ());
+                value_data_. resize (capacity_, value_type ());
+                filled_ = (std::min) (capacity_, filled_);
+            }
+            else {
+                index_data_. resize (capacity_);
+                value_data_. resize (capacity_);
+                filled_ = 0;
+            }
+            storage_invariants ();
+        }
+
+        // Element support
+        BOOST_UBLAS_INLINE
+        pointer find_element (size_type i) {
+            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
+        }
+        BOOST_UBLAS_INLINE
+        const_pointer find_element (size_type i) const {
+            const_subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            if (it == index_data_.begin () + filled_ || *it != k_based (i))
+                return 0;
+            return &value_data_ [it - index_data_.begin ()];
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            const_subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            if (it == index_data_.begin () + filled_ || *it != k_based (i))
+                return zero_;
+            return value_data_ [it - index_data_.begin ()];
+        }
+        BOOST_UBLAS_INLINE
+        true_reference ref (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            if (it == index_data_.begin () + filled_ || *it != k_based (i))
+                return insert_element (i, value_type/*zero*/());
+            else
+                return value_data_ [it - index_data_.begin ()];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+#ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE
+            return ref (i) ;
+#else
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return reference (*this, i);
+#endif
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, const_reference t) {
+            BOOST_UBLAS_CHECK (!find_element (i), bad_index ());        // duplicate element
+            if (filled_ >= capacity_)
+                reserve (2 * capacity_, true);
+            subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            // ISSUE max_capacity limit due to difference_type
+            typename std::iterator_traits<subiterator_type>::difference_type n = it - index_data_.begin ();
+            BOOST_UBLAS_CHECK (filled_ == 0 || filled_ == typename index_array_type::size_type (n) || *it != k_based (i), internal_logic ());   // duplicate found by lower_bound
+            ++ filled_;
+            it = index_data_.begin () + n;
+            std::copy_backward (it, index_data_.begin () + filled_ - 1, index_data_.begin () + filled_);
+            *it = k_based (i);
+            typename value_array_type::iterator itt (value_data_.begin () + n);
+            std::copy_backward (itt, value_data_.begin () + filled_ - 1, value_data_.begin () + filled_);
+            *itt = t;
+            storage_invariants ();
+            return *itt;
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i) {
+            subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            typename std::iterator_traits<subiterator_type>::difference_type  n = it - index_data_.begin ();
+            if (filled_ > typename index_array_type::size_type (n) && *it == k_based (i)) {
+                std::copy (it + 1, index_data_.begin () + filled_, it);
+                typename value_array_type::iterator itt (value_data_.begin () + n);
+                std::copy (itt + 1, value_data_.begin () + filled_, itt);
+                -- filled_;
+            }
+            storage_invariants ();
+        }
+
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            filled_ = 0;
+            storage_invariants ();
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        compressed_vector &operator = (const compressed_vector &v) {
+            if (this != &v) {
+                size_ = v.size_;
+                capacity_ = v.capacity_;
+                filled_ = v.filled_;
+                index_data_ = v.index_data_;
+                value_data_ = v.value_data_;
+            }
+            storage_invariants ();
+            return *this;
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        compressed_vector &operator = (const vector_container<C> &v) {
+            resize (v ().size (), false);
+            assign (v);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        compressed_vector &assign_temporary (compressed_vector &v) {
+            swap (v);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_vector &operator = (const vector_expression<AE> &ae) {
+            self_type temporary (ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_vector &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+
+        // Computed assignment
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_vector &operator += (const vector_expression<AE> &ae) {
+            self_type temporary (*this + ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        compressed_vector &operator += (const vector_container<C> &v) {
+            plus_assign (v);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_vector &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_vector &operator -= (const vector_expression<AE> &ae) {
+            self_type temporary (*this - ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        compressed_vector &operator -= (const vector_container<C> &v) {
+            minus_assign (v);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        compressed_vector &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        compressed_vector &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        compressed_vector &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (compressed_vector &v) {
+            if (this != &v) {
+                std::swap (size_, v.size_);
+                std::swap (capacity_, v.capacity_);
+                std::swap (filled_, v.filled_);
+                index_data_.swap (v.index_data_);
+                value_data_.swap (v.value_data_);
+            }
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (compressed_vector &v1, compressed_vector &v2) {
+            v1.swap (v2);
+        }
+
+        // Back element insertion and erasure
+        BOOST_UBLAS_INLINE
+        void push_back (size_type i, const_reference t) {
+            BOOST_UBLAS_CHECK (filled_ == 0 || index_data_ [filled_ - 1] < k_based (i), external_logic ());
+            if (filled_ >= capacity_)
+                reserve (2 * capacity_, true);
+            BOOST_UBLAS_CHECK (filled_ < capacity_, internal_logic ());
+            index_data_ [filled_] = k_based (i);
+            value_data_ [filled_] = t;
+            ++ filled_;
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        void pop_back () {
+            BOOST_UBLAS_CHECK (filled_ > 0, external_logic ());
+            -- filled_;
+            storage_invariants ();
+        }
+
+        // Iterator types
+    private:
+        // Use index array iterator
+        typedef typename IA::const_iterator const_subiterator_type;
+        typedef typename IA::iterator subiterator_type;
+
+        BOOST_UBLAS_INLINE
+        true_reference at_element (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            BOOST_UBLAS_CHECK (it != index_data_.begin () + filled_ && *it == k_based (i), bad_index ());
+            return value_data_ [it - index_data_.begin ()];
+        }
+
+    public:
+        class const_iterator;
+        class iterator;
+
+        // Element lookup
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+        const_iterator find (size_type i) const {
+            return const_iterator (*this, detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+        iterator find (size_type i) {
+            return iterator (*this, detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+        }
+
+
+        class const_iterator:
+            public container_const_reference<compressed_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator, value_type> {
+        public:
+            typedef typename compressed_vector::value_type value_type;
+            typedef typename compressed_vector::difference_type difference_type;
+            typedef typename compressed_vector::const_reference reference;
+            typedef const typename compressed_vector::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &v, const const_subiterator_type &it):
+                container_const_reference<self_type> (v), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return (*this) ().value_data_ [it_ - (*this) ().index_data_.begin ()];
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().end (), bad_index ());
+                BOOST_UBLAS_CHECK ((*this) ().zero_based (*it_) < (*this) ().size (), bad_index ());
+                return (*this) ().zero_based (*it_);
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end ();
+        }
+
+        class iterator:
+            public container_reference<compressed_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator, value_type> {
+        public:
+            typedef typename compressed_vector::value_type value_type;
+            typedef typename compressed_vector::difference_type difference_type;
+            typedef typename compressed_vector::true_reference reference;
+            typedef typename compressed_vector::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &v, const subiterator_type &it):
+                container_reference<self_type> (v), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return (*this) ().value_data_ [it_ - (*this) ().index_data_.begin ()];
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().end (), bad_index ());
+                BOOST_UBLAS_CHECK ((*this) ().zero_based (*it_) < (*this) ().size (), bad_index ());
+                return (*this) ().zero_based (*it_);
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (size_);
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+            serialization::collection_size_type s (size_);
+            ar & serialization::make_nvp("size",s);
+            if (Archive::is_loading::value) {
+                size_ = s;
+            }
+            // ISSUE: filled may be much less than capacity
+            // ISSUE: index_data_ and value_data_ are undefined between filled and capacity (trouble with 'nan'-values)
+            ar & serialization::make_nvp("capacity", capacity_);
+            ar & serialization::make_nvp("filled", filled_);
+            ar & serialization::make_nvp("index_data", index_data_);
+            ar & serialization::make_nvp("value_data", value_data_);
+            storage_invariants();
+        }
+
+    private:
+        void storage_invariants () const
+        {
+            BOOST_UBLAS_CHECK (capacity_ == index_data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (capacity_ == value_data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (filled_ <= capacity_, internal_logic ());
+            BOOST_UBLAS_CHECK ((0 == filled_) || (zero_based(index_data_[filled_ - 1]) < size_), internal_logic ());
+        }
+
+        size_type size_;
+        typename index_array_type::size_type capacity_;
+        typename index_array_type::size_type filled_;
+        index_array_type index_data_;
+        value_array_type value_data_;
+        static const value_type zero_;
+
+        BOOST_UBLAS_INLINE
+        static size_type zero_based (size_type k_based_index) {
+            return k_based_index - IB;
+        }
+        BOOST_UBLAS_INLINE
+        static size_type k_based (size_type zero_based_index) {
+            return zero_based_index + IB;
+        }
+
+        friend class iterator;
+        friend class const_iterator;
+    };
+
+    template<class T, std::size_t IB, class IA, class TA>
+    const typename compressed_vector<T, IB, IA, TA>::value_type compressed_vector<T, IB, IA, TA>::zero_ = value_type/*zero*/();
+
+    // Thanks to Kresimir Fresl for extending this to cover different index bases.
+
+    /** \brief Coordimate array based sparse vector
+     *
+     * a sparse vector of values of type \c T of variable size. The non zero values are stored 
+     * as two seperate arrays: an index array and a value array. The arrays may be out of order 
+     * with multiple entries for each vector element. If there are multiple values for the same 
+     * index the sum of these values is the real value. It is way more efficient for inserting values
+     * than a \c compressed_vector but less memory efficient. Also linearly parsing a vector can 
+     * be longer in specific cases than a \c compressed_vector.
+     *
+     * For a n-dimensional sorted coordinate vector and \f$ 0 \leq i < n\f$ the non-zero elements 
+     * \f$v_i\f$ are mapped to consecutive elements of the index and value container, i.e. for 
+     * elements \f$k = v_{i_1}\f$ and \f$k + 1 = v_{i_2}\f$ of these containers holds \f$i_1 < i_2\f$.
+     *
+     * Supported parameters for the adapted array (indices and values) are \c unbounded_array<> ,
+     * \c bounded_array<> and \c std::vector<>.
+     *
+     * \tparam T the type of object stored in the vector (like double, float, complex, etc...)
+     * \tparam IB the index base of the compressed vector. Default is 0. Other supported value is 1
+     * \tparam IA the type of adapted array for indices. Default is \c unbounded_array<std::size_t>
+     * \tparam TA the type of adapted array for values. Default is unbounded_array<T>
+     */
+    template<class T, std::size_t IB, class IA, class TA>
+    class coordinate_vector:
+        public vector_container<coordinate_vector<T, IB, IA, TA> > {
+
+        typedef T &true_reference;
+        typedef T *pointer;
+        typedef const T *const_pointer;
+        typedef coordinate_vector<T, IB, IA, TA> self_type;
+    public:
+#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
+        using vector_container<self_type>::operator ();
+#endif
+        // ISSUE require type consistency check
+        // is_convertable (IA::size_type, TA::size_type)
+        typedef typename IA::value_type size_type;
+        typedef typename IA::difference_type difference_type;
+        typedef T value_type;
+        typedef const T &const_reference;
+#ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE
+        typedef T &reference;
+#else
+        typedef sparse_vector_element<self_type> reference;
+#endif
+        typedef IA index_array_type;
+        typedef TA value_array_type;
+        typedef const vector_reference<const self_type> const_closure_type;
+        typedef vector_reference<self_type> closure_type;
+        typedef self_type vector_temporary_type;
+        typedef sparse_tag storage_category;
+
+        // Construction and destruction
+        BOOST_UBLAS_INLINE
+        coordinate_vector ():
+            vector_container<self_type> (),
+            size_ (0), capacity_ (restrict_capacity (0)),
+            filled_ (0), sorted_filled_ (filled_), sorted_ (true),
+            index_data_ (capacity_), value_data_ (capacity_) {
+            storage_invariants ();
+        }
+        explicit BOOST_UBLAS_INLINE
+        coordinate_vector (size_type size, size_type non_zeros = 0):
+            vector_container<self_type> (),
+            size_ (size), capacity_ (restrict_capacity (non_zeros)),
+            filled_ (0), sorted_filled_ (filled_), sorted_ (true),
+            index_data_ (capacity_), value_data_ (capacity_) {
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        coordinate_vector (const coordinate_vector &v):
+            vector_container<self_type> (),
+            size_ (v.size_), capacity_ (v.capacity_),
+            filled_ (v.filled_), sorted_filled_ (v.sorted_filled_), sorted_ (v.sorted_),
+            index_data_ (v.index_data_), value_data_ (v.value_data_) {
+            storage_invariants ();
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_vector (const vector_expression<AE> &ae, size_type non_zeros = 0):
+            vector_container<self_type> (),
+            size_ (ae ().size ()), capacity_ (restrict_capacity (non_zeros)),
+            filled_ (0), sorted_filled_ (filled_), sorted_ (true),
+            index_data_ (capacity_), value_data_ (capacity_) {
+            storage_invariants ();
+            vector_assign<scalar_assign> (*this, ae);
+        }
+
+        // Accessors
+        BOOST_UBLAS_INLINE
+        size_type size () const {
+            return size_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz_capacity () const {
+            return capacity_;
+        }
+        BOOST_UBLAS_INLINE
+        size_type nnz () const {
+            return filled_;
+        }
+
+        // Storage accessors
+        BOOST_UBLAS_INLINE
+        static size_type index_base () {
+            return IB;
+        }
+        BOOST_UBLAS_INLINE
+        typename index_array_type::size_type filled () const {
+            return filled_;
+        }
+        BOOST_UBLAS_INLINE
+        const index_array_type &index_data () const {
+            return index_data_;
+        }
+        BOOST_UBLAS_INLINE
+        const value_array_type &value_data () const {
+            return value_data_;
+        }
+        BOOST_UBLAS_INLINE
+        void set_filled (const typename index_array_type::size_type &sorted, const typename index_array_type::size_type &filled) {
+            sorted_filled_ = sorted;
+            filled_ = filled;
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        index_array_type &index_data () {
+            return index_data_;
+        }
+        BOOST_UBLAS_INLINE
+        value_array_type &value_data () {
+            return value_data_;
+        }
+
+        // Resizing
+    private:
+        BOOST_UBLAS_INLINE
+        size_type restrict_capacity (size_type non_zeros) const {
+             // minimum non_zeros
+             non_zeros = (std::max) (non_zeros, size_type (1));
+             // ISSUE no maximum as coordinate may contain inserted duplicates
+             return non_zeros;
+        }
+    public:
+        BOOST_UBLAS_INLINE
+        void resize (size_type size, bool preserve = true) {
+            if (preserve)
+                sort ();    // remove duplicate elements.
+            size_ = size;
+            capacity_ = restrict_capacity (capacity_);
+            if (preserve) {
+                index_data_. resize (capacity_, size_type ());
+                value_data_. resize (capacity_, value_type ());
+                filled_ = (std::min) (capacity_, filled_);
+                while ((filled_ > 0) && (zero_based(index_data_[filled_ - 1]) >= size)) {
+                    --filled_;
+                }
+            }
+            else {
+                index_data_. resize (capacity_);
+                value_data_. resize (capacity_);
+                filled_ = 0;
+            }
+            sorted_filled_ = filled_;
+            storage_invariants ();
+        }
+        // Reserving
+        BOOST_UBLAS_INLINE
+        void reserve (size_type non_zeros, bool preserve = true) {
+            if (preserve)
+                sort ();    // remove duplicate elements.
+            capacity_ = restrict_capacity (non_zeros);
+            if (preserve) {
+                index_data_. resize (capacity_, size_type ());
+                value_data_. resize (capacity_, value_type ());
+                filled_ = (std::min) (capacity_, filled_);
+                }
+            else {
+                index_data_. resize (capacity_);
+                value_data_. resize (capacity_);
+                filled_ = 0;
+            }
+            sorted_filled_ = filled_;
+            storage_invariants ();
+        }
+
+        // Element support
+        BOOST_UBLAS_INLINE
+        pointer find_element (size_type i) {
+            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
+        }
+        BOOST_UBLAS_INLINE
+        const_pointer find_element (size_type i) const {
+            sort ();
+            const_subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            if (it == index_data_.begin () + filled_ || *it != k_based (i))
+                return 0;
+            return &value_data_ [it - index_data_.begin ()];
+        }
+
+        // Element access
+        BOOST_UBLAS_INLINE
+        const_reference operator () (size_type i) const {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            sort ();
+            const_subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            if (it == index_data_.begin () + filled_ || *it != k_based (i))
+                return zero_;
+            return value_data_ [it - index_data_.begin ()];
+        }
+        BOOST_UBLAS_INLINE
+        true_reference ref (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            sort ();
+            subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            if (it == index_data_.begin () + filled_ || *it != k_based (i))
+                return insert_element (i, value_type/*zero*/());
+            else
+                return value_data_ [it - index_data_.begin ()];
+        }
+        BOOST_UBLAS_INLINE
+        reference operator () (size_type i) {
+#ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE
+            return ref (i);
+#else
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            return reference (*this, i);
+#endif
+        }
+
+        BOOST_UBLAS_INLINE
+        const_reference operator [] (size_type i) const {
+            return (*this) (i);
+        }
+        BOOST_UBLAS_INLINE
+        reference operator [] (size_type i) {
+            return (*this) (i);
+        }
+
+        // Element assignment
+        BOOST_UBLAS_INLINE
+        void append_element (size_type i, const_reference t) {
+            if (filled_ >= capacity_)
+                reserve (2 * filled_, true);
+            BOOST_UBLAS_CHECK (filled_ < capacity_, internal_logic ());
+            index_data_ [filled_] = k_based (i);
+            value_data_ [filled_] = t;
+            ++ filled_;
+            sorted_ = false;
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        true_reference insert_element (size_type i, const_reference t) {
+            BOOST_UBLAS_CHECK (!find_element (i), bad_index ());        // duplicate element
+            append_element (i, t);
+            return value_data_ [filled_ - 1];
+        }
+        BOOST_UBLAS_INLINE
+        void erase_element (size_type i) {
+            sort ();
+            subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            typename std::iterator_traits<subiterator_type>::difference_type n = it - index_data_.begin ();
+            if (filled_ > typename index_array_type::size_type (n) && *it == k_based (i)) {
+                std::copy (it + 1, index_data_.begin () + filled_, it);
+                typename value_array_type::iterator itt (value_data_.begin () + n);
+                std::copy (itt + 1, value_data_.begin () + filled_, itt);
+                -- filled_;
+                sorted_filled_ = filled_;
+            }
+            storage_invariants ();
+        }
+
+        // Zeroing
+        BOOST_UBLAS_INLINE
+        void clear () {
+            filled_ = 0;
+            sorted_filled_ = filled_;
+            sorted_ = true;
+            storage_invariants ();
+        }
+
+        // Assignment
+        BOOST_UBLAS_INLINE
+        coordinate_vector &operator = (const coordinate_vector &v) {
+            if (this != &v) {
+                size_ = v.size_;
+                capacity_ = v.capacity_;
+                filled_ = v.filled_;
+                sorted_filled_ = v.sorted_filled_;
+                sorted_ = v.sorted_;
+                index_data_ = v.index_data_;
+                value_data_ = v.value_data_;
+            }
+            storage_invariants ();
+            return *this;
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        coordinate_vector &operator = (const vector_container<C> &v) {
+            resize (v ().size (), false);
+            assign (v);
+            return *this;
+        }
+        BOOST_UBLAS_INLINE
+        coordinate_vector &assign_temporary (coordinate_vector &v) {
+            swap (v);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_vector &operator = (const vector_expression<AE> &ae) {
+            self_type temporary (ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_vector &assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_assign> (*this, ae);
+            return *this;
+        }
+
+        // Computed assignment
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_vector &operator += (const vector_expression<AE> &ae) {
+            self_type temporary (*this + ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        coordinate_vector &operator += (const vector_container<C> &v) {
+            plus_assign (v);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_vector &plus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_plus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_vector &operator -= (const vector_expression<AE> &ae) {
+            self_type temporary (*this - ae, capacity_);
+            return assign_temporary (temporary);
+        }
+        template<class C>          // Container assignment without temporary
+        BOOST_UBLAS_INLINE
+        coordinate_vector &operator -= (const vector_container<C> &v) {
+            minus_assign (v);
+            return *this;
+        }
+        template<class AE>
+        BOOST_UBLAS_INLINE
+        coordinate_vector &minus_assign (const vector_expression<AE> &ae) {
+            vector_assign<scalar_minus_assign> (*this, ae);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        coordinate_vector &operator *= (const AT &at) {
+            vector_assign_scalar<scalar_multiplies_assign> (*this, at);
+            return *this;
+        }
+        template<class AT>
+        BOOST_UBLAS_INLINE
+        coordinate_vector &operator /= (const AT &at) {
+            vector_assign_scalar<scalar_divides_assign> (*this, at);
+            return *this;
+        }
+
+        // Swapping
+        BOOST_UBLAS_INLINE
+        void swap (coordinate_vector &v) {
+            if (this != &v) {
+                std::swap (size_, v.size_);
+                std::swap (capacity_, v.capacity_);
+                std::swap (filled_, v.filled_);
+                std::swap (sorted_filled_, v.sorted_filled_);
+                std::swap (sorted_, v.sorted_);
+                index_data_.swap (v.index_data_);
+                value_data_.swap (v.value_data_);
+            }
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        friend void swap (coordinate_vector &v1, coordinate_vector &v2) {
+            v1.swap (v2);
+        }
+
+        // replacement if STL lower bound algorithm for use of inplace_merge
+        size_type lower_bound (size_type beg, size_type end, size_type target) const {
+            while (end > beg) {
+                size_type mid = (beg + end) / 2;
+                if (index_data_[mid] < index_data_[target]) {
+                    beg = mid + 1;
+                } else {
+                    end = mid;
+                }
+            }
+            return beg;
+        }
+
+        // specialized replacement of STL inplace_merge to avoid compilation
+        // problems with respect to the array_triple iterator
+        void inplace_merge (size_type beg, size_type mid, size_type end) const {
+            size_type len_lef = mid - beg;
+            size_type len_rig = end - mid;
+
+            if (len_lef == 1 && len_rig == 1) {
+                if (index_data_[mid] < index_data_[beg]) {
+                    std::swap(index_data_[beg], index_data_[mid]);
+                    std::swap(value_data_[beg], value_data_[mid]);
+                }
+            } else if (len_lef > 0 && len_rig > 0) {
+                size_type lef_mid, rig_mid;
+                if (len_lef >= len_rig) {
+                    lef_mid = (beg + mid) / 2;
+                    rig_mid = lower_bound(mid, end, lef_mid);
+                } else {
+                    rig_mid = (mid + end) / 2;
+                    lef_mid = lower_bound(beg, mid, rig_mid);
+                }
+                std::rotate(&index_data_[0] + lef_mid, &index_data_[0] + mid, &index_data_[0] + rig_mid);
+                std::rotate(&value_data_[0] + lef_mid, &value_data_[0] + mid, &value_data_[0] + rig_mid);
+
+                size_type new_mid = lef_mid + rig_mid - mid;
+                inplace_merge(beg, lef_mid, new_mid);
+                inplace_merge(new_mid, rig_mid, end);
+            }
+        }
+
+        // Sorting and summation of duplicates
+        BOOST_UBLAS_INLINE
+        void sort () const {
+            if (! sorted_ && filled_ > 0) {
+                typedef index_pair_array<index_array_type, value_array_type> array_pair;
+                array_pair ipa (filled_, index_data_, value_data_);
+#ifndef BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT
+                const typename array_pair::iterator iunsorted = ipa.begin () + sorted_filled_;
+                // sort new elements and merge
+                std::sort (iunsorted, ipa.end ());
+                inplace_merge(0, sorted_filled_, filled_);
+#else
+                const typename array_pair::iterator iunsorted = ipa.begin ();
+                std::sort (iunsorted, ipa.end ());
+#endif
+
+                // sum duplicates with += and remove
+                size_type filled = 0;
+                for (size_type i = 1; i < filled_; ++ i) {
+                    if (index_data_ [filled] != index_data_ [i]) {
+                        ++ filled;
+                        if (filled != i) {
+                            index_data_ [filled] = index_data_ [i];
+                            value_data_ [filled] = value_data_ [i];
+                        }
+                    } else {
+                        value_data_ [filled] += value_data_ [i];
+                    }
+                }
+                filled_ = filled + 1;
+                sorted_filled_ = filled_;
+                sorted_ = true;
+                storage_invariants ();
+            }
+        }
+
+        // Back element insertion and erasure
+        BOOST_UBLAS_INLINE
+        void push_back (size_type i, const_reference t) {
+            // must maintain sort order
+            BOOST_UBLAS_CHECK (sorted_ && (filled_ == 0 || index_data_ [filled_ - 1] < k_based (i)), external_logic ());
+            if (filled_ >= capacity_)
+                reserve (2 * filled_, true);
+            BOOST_UBLAS_CHECK (filled_ < capacity_, internal_logic ());
+            index_data_ [filled_] = k_based (i);
+            value_data_ [filled_] = t;
+            ++ filled_;
+            sorted_filled_ = filled_;
+            storage_invariants ();
+        }
+        BOOST_UBLAS_INLINE
+        void pop_back () {
+            // ISSUE invariants could be simpilfied if sorted required as precondition
+            BOOST_UBLAS_CHECK (filled_ > 0, external_logic ());
+            -- filled_;
+            sorted_filled_ = (std::min) (sorted_filled_, filled_);
+            sorted_ = sorted_filled_ = filled_;
+            storage_invariants ();
+        }
+
+        // Iterator types
+    private:
+        // Use index array iterator
+        typedef typename IA::const_iterator const_subiterator_type;
+        typedef typename IA::iterator subiterator_type;
+
+        BOOST_UBLAS_INLINE
+        true_reference at_element (size_type i) {
+            BOOST_UBLAS_CHECK (i < size_, bad_index ());
+            sort ();
+            subiterator_type it (detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+            BOOST_UBLAS_CHECK (it != index_data_.begin () + filled_ && *it == k_based (i), bad_index ());
+            return value_data_ [it - index_data_.begin ()];
+        }
+
+    public:
+        class const_iterator;
+        class iterator;
+
+        // Element lookup
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+        const_iterator find (size_type i) const {
+            sort ();
+            return const_iterator (*this, detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+        }
+        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
+        iterator find (size_type i) {
+            sort ();
+            return iterator (*this, detail::lower_bound (index_data_.begin (), index_data_.begin () + filled_, k_based (i), std::less<size_type> ()));
+        }
+
+
+        class const_iterator:
+            public container_const_reference<coordinate_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               const_iterator, value_type> {
+        public:
+            typedef typename coordinate_vector::value_type value_type;
+            typedef typename coordinate_vector::difference_type difference_type;
+            typedef typename coordinate_vector::const_reference reference;
+            typedef const typename coordinate_vector::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            const_iterator ():
+                container_const_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const self_type &v, const const_subiterator_type &it):
+                container_const_reference<self_type> (v), it_ (it) {}
+            BOOST_UBLAS_INLINE
+            const_iterator (const typename self_type::iterator &it):  // ISSUE self_type:: stops VC8 using std::iterator here
+                container_const_reference<self_type> (it ()), it_ (it.it_) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            const_iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            const_iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            const_reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return (*this) ().value_data_ [it_ - (*this) ().index_data_.begin ()];
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().end (), bad_index ());
+                BOOST_UBLAS_CHECK ((*this) ().zero_based (*it_) < (*this) ().size (), bad_index ());
+                return (*this) ().zero_based (*it_);
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            const_iterator &operator = (const const_iterator &it) {
+                container_const_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const const_iterator &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+
+        private:
+            const_subiterator_type it_;
+        };
+
+        BOOST_UBLAS_INLINE
+        const_iterator begin () const {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cbegin () const {
+            return begin();
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator end () const {
+            return find (size_);
+        }
+        BOOST_UBLAS_INLINE
+        const_iterator cend () const {
+            return end();
+        }
+
+        class iterator:
+            public container_reference<coordinate_vector>,
+            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,
+                                               iterator, value_type> {
+        public:
+            typedef typename coordinate_vector::value_type value_type;
+            typedef typename coordinate_vector::difference_type difference_type;
+            typedef typename coordinate_vector::true_reference reference;
+            typedef typename coordinate_vector::pointer pointer;
+
+            // Construction and destruction
+            BOOST_UBLAS_INLINE
+            iterator ():
+                container_reference<self_type> (), it_ () {}
+            BOOST_UBLAS_INLINE
+            iterator (self_type &v, const subiterator_type &it):
+                container_reference<self_type> (v), it_ (it) {}
+
+            // Arithmetic
+            BOOST_UBLAS_INLINE
+            iterator &operator ++ () {
+                ++ it_;
+                return *this;
+            }
+            BOOST_UBLAS_INLINE
+            iterator &operator -- () {
+                -- it_;
+                return *this;
+            }
+
+            // Dereference
+            BOOST_UBLAS_INLINE
+            reference operator * () const {
+                BOOST_UBLAS_CHECK (index () < (*this) ().size (), bad_index ());
+                return (*this) ().value_data_ [it_ - (*this) ().index_data_.begin ()];
+            }
+
+            // Index
+            BOOST_UBLAS_INLINE
+            size_type index () const {
+                BOOST_UBLAS_CHECK (*this != (*this) ().end (), bad_index ());
+                BOOST_UBLAS_CHECK ((*this) ().zero_based (*it_) < (*this) ().size (), bad_index ());
+                return (*this) ().zero_based (*it_);
+            }
+
+            // Assignment
+            BOOST_UBLAS_INLINE
+            iterator &operator = (const iterator &it) {
+                container_reference<self_type>::assign (&it ());
+                it_ = it.it_;
+                return *this;
+            }
+
+            // Comparison
+            BOOST_UBLAS_INLINE
+            bool operator == (const iterator &it) const {
+                BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
+                return it_ == it.it_;
+            }
+
+        private:
+            subiterator_type it_;
+
+            friend class const_iterator;
+        };
+
+        BOOST_UBLAS_INLINE
+        iterator begin () {
+            return find (0);
+        }
+        BOOST_UBLAS_INLINE
+        iterator end () {
+            return find (size_);
+        }
+
+        // Reverse iterator
+        typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
+        typedef reverse_iterator_base<iterator> reverse_iterator;
+
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rbegin () const {
+            return const_reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crbegin () const {
+            return rbegin ();
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator rend () const {
+            return const_reverse_iterator (begin ());
+        }
+        BOOST_UBLAS_INLINE
+        const_reverse_iterator crend () const {
+            return rend ();
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rbegin () {
+            return reverse_iterator (end ());
+        }
+        BOOST_UBLAS_INLINE
+        reverse_iterator rend () {
+            return reverse_iterator (begin ());
+        }
+
+         // Serialization
+        template<class Archive>
+        void serialize(Archive & ar, const unsigned int /* file_version */){
+            serialization::collection_size_type s (size_);
+            ar & serialization::make_nvp("size",s);
+            if (Archive::is_loading::value) {
+                size_ = s;
+            }
+            // ISSUE: filled may be much less than capacity
+            // ISSUE: index_data_ and value_data_ are undefined between filled and capacity (trouble with 'nan'-values)
+            ar & serialization::make_nvp("capacity", capacity_);
+            ar & serialization::make_nvp("filled", filled_);
+            ar & serialization::make_nvp("sorted_filled", sorted_filled_);
+            ar & serialization::make_nvp("sorted", sorted_);
+            ar & serialization::make_nvp("index_data", index_data_);
+            ar & serialization::make_nvp("value_data", value_data_);
+            storage_invariants();
+        }
+
+    private:
+        void storage_invariants () const
+        {
+            BOOST_UBLAS_CHECK (capacity_ == index_data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (capacity_ == value_data_.size (), internal_logic ());
+            BOOST_UBLAS_CHECK (filled_ <= capacity_, internal_logic ());
+            BOOST_UBLAS_CHECK (sorted_filled_ <= filled_, internal_logic ());
+            BOOST_UBLAS_CHECK (sorted_ == (sorted_filled_ == filled_), internal_logic ());
+            BOOST_UBLAS_CHECK ((0 == filled_) || (zero_based(index_data_[filled_ - 1]) < size_), internal_logic ());
+        }
+
+        size_type size_;
+        size_type capacity_;
+        mutable typename index_array_type::size_type filled_;
+        mutable typename index_array_type::size_type sorted_filled_;
+        mutable bool sorted_;
+        mutable index_array_type index_data_;
+        mutable value_array_type value_data_;
+        static const value_type zero_;
+
+        BOOST_UBLAS_INLINE
+        static size_type zero_based (size_type k_based_index) {
+            return k_based_index - IB;
+        }
+        BOOST_UBLAS_INLINE
+        static size_type k_based (size_type zero_based_index) {
+            return zero_based_index + IB;
+        }
+
+        friend class iterator;
+        friend class const_iterator;
+    };
+
+    template<class T, std::size_t IB, class IA, class TA>
+    const typename coordinate_vector<T, IB, IA, TA>::value_type coordinate_vector<T, IB, IA, TA>::zero_ = value_type/*zero*/();
+
+}}}
+
+#endif
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..16cd001
--- /dev/null
+++ b/index.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=doc/index.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="doc/index.html">doc/index.html</a> &nbsp;<hr>
+<p>Distributed under the Boost Software License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+</body>
+</html>
diff --git a/meta/libraries.json b/meta/libraries.json
new file mode 100644
index 0000000..68be737
--- /dev/null
+++ b/meta/libraries.json
@@ -0,0 +1,15 @@
+{
+    "key": "numeric/ublas",
+    "name": "uBLAS",
+    "authors": [
+        "Joerg Walter",
+        "Mathias Koch"
+    ],
+    "description": "uBLAS provides matrix and vector classes as well as basic linear algebra routines. Several dense, packed and sparse storage schemes are supported.",
+    "category": [
+        "Math"
+    ],
+    "maintainers": [
+        "David Bellot <david.bellot -at- gmail.com>"
+    ]
+}
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
new file mode 100644
index 0000000..bd4092e
--- /dev/null
+++ b/test/Jamfile.v2
@@ -0,0 +1,222 @@
+# Copyright (c) 2004-2011 Michael Stevens, David Bellot
+# Use, modification and distribution are subject to the
+# Boost Software License, Version 1.0. (See accompanying file
+# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# Bring in rules for testing
+import testing ;
+
+# Define features to test:
+#  Value types: USE_FLOAT USE_DOUBLE USE_STD_COMPLEX
+#  Proxies: USE_RANGE USE_SLICE
+#  Storage types: USE_BOUNDED_ARRAY USE_UNBOUNDED_ARRAY
+#  Vector types: USE_STD_VECTOR USE_BOUNDED_VECTOR
+#  Matrix types: USE_MATRIX USE_BOUNDED_MATRIX USE_VECTOR_OF_VECTOR
+#  Adaptors: USE_ADAPTOR
+
+UBLAS_TESTSET = [ modules.peek : UBLAS_TESTSET ] ;
+UBLAS_TESTSET ?=
+            USE_DOUBLE USE_STD_COMPLEX
+            USE_RANGE USE_SLICE
+            USE_UNBOUNDED_ARRAY USE_STD_VECTOR USE_BOUNDED_VECTOR USE_MATRIX
+            ;
+
+#  Sparse storage: USE_MAP_ARRAY USE_STD_MAP
+#  Sparse vectors: USE_MAPPED_VECTOR USE_COMPRESSED_VECTOR USE_COORDINATE_VECTOR
+#  Sparse matrices: USE_MAPPED_MATRIX USE_COMPRESSED_MATRIX USE_COORDINATE_MATRIX USE_MAPPED_VECTOR_OF_MAPPED_VECTOR USE_GENERALIZED_VECTOR_OF_VECTOR
+
+UBLAS_TESTSET_SPARSE = [ modules.peek : UBLAS_TESTSET_SPARSE ] ;
+UBLAS_TESTSET_SPARSE ?= 
+            USE_DOUBLE USE_STD_COMPLEX
+            # USE_RANGE USE_SLICE	 # Too complex for regression testing
+            USE_UNBOUNDED_ARRAY
+			USE_MAP_ARRAY USE_STD_MAP
+            USE_MAPPED_VECTOR USE_COMPRESSED_VECTOR 
+            USE_MAPPED_MATRIX USE_COMPRESSED_MATRIX 
+			;
+# Generalize VofV still failing
+#            USE_GENERALIZED_VECTOR_OF_VECTOR
+
+UBLAS_TESTSET_SPARSE_COO = [ modules.peek : UBLAS_TESTSET_SPARSE_COO ] ;
+UBLAS_TESTSET_SPARSE_COO ?= 
+            USE_DOUBLE USE_STD_COMPLEX
+            USE_UNBOUNDED_ARRAY
+            USE_COORDINATE_VECTOR
+            USE_COORDINATE_MATRIX 
+			;
+
+
+# Project settings
+project
+    : requirements
+       <define>BOOST_UBLAS_NO_EXCEPTIONS
+       <toolset>vacpp:<define>"BOOST_UBLAS_NO_ELEMENT_PROXIES"
+    ;
+
+
+test-suite numeric/uBLAS
+    : [ run test1.cpp
+            test11.cpp
+            test12.cpp
+            test13.cpp
+        : # args
+        : # input files
+        : # requirements
+            <define>$(UBLAS_TESTSET)
+      ]
+      [ run test2.cpp
+            test21.cpp
+            test22.cpp
+            test23.cpp
+        : : :
+            <define>$(UBLAS_TESTSET)
+      ]
+      [ run test3.cpp
+            test31.cpp
+            test32.cpp
+            test33.cpp
+        : : :
+            <define>$(UBLAS_TESTSET_SPARSE)
+      ]
+      [ run test3.cpp
+            test31.cpp
+            test32.cpp
+            test33.cpp
+        : : :
+            <define>$(UBLAS_TESTSET_SPARSE_COO)
+	: test3_coo
+	:
+      ]
+      [ run test3.cpp
+            test31.cpp
+            test32.cpp
+            test33.cpp
+        : : :
+            <define>USE_FLOAT
+            <define>USE_DOUBLE 
+            <define>USE_STD_COMPLEX 
+            <define>USE_STD_MAP
+            <define>USE_MAPPED_VECTOR_OF_MAPPED_VECTOR 
+        : test3_mvov 
+        :
+      ]
+      [ run test4.cpp
+            test42.cpp
+            test43.cpp
+        : : :
+            <define>$(UBLAS_TESTSET)
+      ]
+      [ run test5.cpp
+            test52.cpp
+            test53.cpp
+        : : :
+            <define>$(UBLAS_TESTSET)
+      ]
+      [ run test6.cpp
+            test62.cpp
+            test63.cpp
+        : : :
+            <define>$(UBLAS_TESTSET)
+      ]
+# Test commented out because boost::interval does not behave like a scalar type
+#      [ run test7.cpp
+#            test71.cpp
+#            test72.cpp
+#            test73.cpp
+#        : : :
+#            <define>BOOST_UBLAS_USE_INTERVAL
+#            <define>$(UBLAS_TESTSET)
+#      ]
+
+      [ run placement_new.cpp
+      ]
+      [ compile concepts.cpp
+        : # requirements
+            <define>EXTERNAL
+#            <define>INTERAL
+#            <define>SKIP_BAD
+            <toolset>intel-linux:<cxxflags>"-Xc"
+            <toolset>darwin:<cxxflags>"-fabi-version=0"
+      ]
+      [ run test_lu.cpp
+      ]
+      [ run triangular_access.cpp
+        : : :
+            <define>NOMESSAGES
+      ]
+      [ run triangular_layout.cpp
+      ]
+      [ run comp_mat_erase.cpp
+      ]
+      [ run sparse_view_test.cpp
+      ]
+      [ run begin_end.cpp
+      ]
+      [ run num_columns.cpp
+      ]
+      [ run num_rows.cpp
+      ]
+      [ run size.cpp
+      ]
+      [ run test_coordinate_matrix_sort.cpp
+      ]
+      [ run test_coordinate_matrix_sort.cpp
+       :
+       :
+       : <define>BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT
+       : test_coordinate_matrix_always_do_full_sort
+       :
+      ]
+      [ run test_complex_norms.cpp
+      ]
+	  [ run test_assignment.cpp
+	  : : : <define>BOOST_UBLAS_COO_ALWAYS_DO_FULL_SORT
+	  : :
+	  ]
+          [ run test_triangular.cpp
+            :
+            :
+            : <library>/boost/timer//boost_timer
+          ]
+	  [ run test_ticket7296.cpp
+	  ]
+      [ run test_inplace_solve.cpp
+        : 
+        : 
+        : <define>$(UBLAS_TESTSET) 
+        : test_inplace_solve_basic
+        :
+      ]
+      [ run test_inplace_solve.cpp
+        : 
+        : 
+        : <define>$(UBLAS_TESTSET_SPARSE) <define>$(UBLAS_TESTSET_SPARSE_COO)
+        : test_inplace_solve_sparse
+        :
+      ]
+      [ run test_inplace_solve.cpp
+        : 
+        : 
+        : <define>USE_MAPPED_VECTOR_OF_MAPPED_VECTOR
+        : test_inplace_solve_mvov
+        :
+      ]
+      [ run test_coordinate_vector_inplace_merge.cpp 
+      ]
+      [ run test_coordinate_matrix_inplace_merge.cpp 
+      ]
+      [ run test_banded_storage_layout.cpp
+        :
+        :
+        :
+        :
+        :
+      ]
+      [ run test_fixed_containers.cpp
+        :
+        :
+        :
+      ]
+      [ run test_matrix_vector.cpp
+      ]
+    ;
diff --git a/test/README b/test/README
new file mode 100644
index 0000000..7611231
--- /dev/null
+++ b/test/README
@@ -0,0 +1,31 @@
+Copyright (c) 2000-2011 Joerg Walter, Mathias Koch, David Bellot
+
+Distributed under the Boost Software License, Version 1.0. (See
+accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+
+uBLAS test director
+	Use boost::test to test various uBLAS containers and expressions
+
+The tests can be used individually or automaticaly as part of the uBLAS regression tests.
+
+The tests are broken down in directorys as follows:
+
+test1 - dense vector and matrix tests
+test2 - BLAS tests
+test3 - sparse vector and matrix tests
+test4 - banded/diagonal matrix tests
+test5 - triangular matrix tests
+test6 - symmetric matrix tests
+test7 - dense vector and matrix tests with boost::numeric::internal values
+
+Each test directory contains:
+	testX.hpp	Headers and types to be tested
+	testX.cpp	Call the test functions for the defined types
+	testX1.cpp	Implements vector tests	
+	testX2.cpp	Implements vector/matrix tests	
+	testX3.cpp	Implements matrix tests	
+
+Missing in these tests
+	a) Runtime result validation.
+	b) Iterator interface tests. Only complete container expressions are tested
diff --git a/test/begin_end.cpp b/test/begin_end.cpp
new file mode 100644
index 0000000..769a51f
--- /dev/null
+++ b/test/begin_end.cpp
@@ -0,0 +1,181 @@
+//  Copyright (c) 2011 David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cmath>
+#include <boost/numeric/ublas/traits/const_iterator_type.hpp>
+#include <boost/numeric/ublas/traits/iterator_type.hpp>
+#include <boost/numeric/ublas/traits/c_array.hpp>
+#include <boost/numeric/ublas/fwd.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_expression.hpp>
+#include <boost/numeric/ublas/operation/begin.hpp>
+#include <boost/numeric/ublas/operation/end.hpp>
+#include <boost/numeric/ublas/tags.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_expression.hpp>
+#include <iostream>
+#include "utils.hpp"
+
+
+static const double TOL(1.0e-5); ///< Used for comparing two real numbers.
+
+#ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+#error "sorry this feature is not supported by your compiler"
+#endif
+
+BOOST_UBLAS_TEST_DEF( test_vector_iteration )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Iteration" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::vector<value_type> vector_type;
+
+    vector_type v(5);
+
+    v(0) = 0.555950;
+    v(1) = 0.108929;
+    v(2) = 0.948014;
+    v(3) = 0.023787;
+    v(4) = 1.023787;
+
+
+    vector_type::size_type ix = 0;
+    for (
+            boost::numeric::ublas::iterator_type<vector_type>::type it = boost::numeric::ublas::begin<vector_type>(v);
+            it != boost::numeric::ublas::end<vector_type>(v);
+            ++it
+    ) {
+        BOOST_UBLAS_DEBUG_TRACE( "*it = " << *it << " ==> " << v(ix) );
+        BOOST_UBLAS_TEST_CHECK( std::abs(*it - v(ix)) <= TOL );
+        ++ix;
+    }
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_vector_const_iteration )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Const Iteration" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::vector<value_type> vector_type;
+
+    vector_type v(5);
+
+    v(0) = 0.555950;
+    v(1) = 0.108929;
+    v(2) = 0.948014;
+    v(3) = 0.023787;
+    v(4) = 1.023787;
+
+
+    vector_type::size_type ix = 0;
+    for (
+            boost::numeric::ublas::const_iterator_type<vector_type>::type it = boost::numeric::ublas::begin<vector_type>(v);
+            it != boost::numeric::ublas::end<vector_type>(v);
+            ++it
+    ) {
+        BOOST_UBLAS_DEBUG_TRACE( "*it = " << *it << " ==> " << v(ix) );
+        BOOST_UBLAS_TEST_CHECK( std::abs(*it - v(ix)) <= TOL );
+        ++ix;
+    }
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_row_major_matrix_iteration )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Iteration" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type;
+    typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::major>::type outer_iterator_type;
+    typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::minor>::type inner_iterator_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    matrix_type::size_type row(0);
+    for (
+            outer_iterator_type outer_it = boost::numeric::ublas::begin<boost::numeric::ublas::tag::major>(A);
+            outer_it != boost::numeric::ublas::end<boost::numeric::ublas::tag::major>(A);
+            ++outer_it
+    ) {
+        matrix_type::size_type col(0);
+
+        for (
+                inner_iterator_type inner_it = boost::numeric::ublas::begin(outer_it);
+                inner_it != boost::numeric::ublas::end(outer_it);
+                ++inner_it
+        ) {
+            BOOST_UBLAS_DEBUG_TRACE( "*it = " << *inner_it << " ==> " << A(row,col) );
+            BOOST_UBLAS_TEST_CHECK( std::abs(*inner_it - A(row,col)) <= TOL );
+
+            ++col;
+        }
+
+        ++row;
+    }
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_col_major_matrix_iteration )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Iteration" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type;
+    typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::major>::type outer_iterator_type;
+    typedef boost::numeric::ublas::iterator_type<matrix_type, boost::numeric::ublas::tag::minor>::type inner_iterator_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    matrix_type::size_type col(0);
+    for (
+            outer_iterator_type outer_it = boost::numeric::ublas::begin<boost::numeric::ublas::tag::major>(A);
+            outer_it != boost::numeric::ublas::end<boost::numeric::ublas::tag::major>(A);
+            ++outer_it
+    ) {
+        matrix_type::size_type row(0);
+
+        for (
+                inner_iterator_type inner_it = boost::numeric::ublas::begin(outer_it);
+                inner_it != boost::numeric::ublas::end(outer_it);
+                ++inner_it
+        ) {
+            BOOST_UBLAS_DEBUG_TRACE( "*it = " << *inner_it << " ==> " << A(row,col) );
+            BOOST_UBLAS_TEST_CHECK( std::abs(*inner_it - A(row,col)) <= TOL );
+
+            ++row;
+        }
+
+        ++col;
+    }
+}
+
+
+int main()
+{
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_vector_iteration );
+    BOOST_UBLAS_TEST_DO( test_vector_const_iteration );
+    BOOST_UBLAS_TEST_DO( test_row_major_matrix_iteration );
+    BOOST_UBLAS_TEST_DO( test_col_major_matrix_iteration );
+
+    BOOST_UBLAS_TEST_END();
+}
diff --git a/test/common/init.hpp b/test/common/init.hpp
new file mode 100644
index 0000000..a9691b4
--- /dev/null
+++ b/test/common/init.hpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2004 Michael Stevens
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * Default construct test when possible
+ */
+
+template <class E>
+struct default_construct
+{
+    static void test() {}
+}; 
+template <class VC>
+struct default_construct<boost::numeric::ublas::vector_container<VC> >
+{
+    static void test ()
+    {
+        VC default_constuct;
+        initialize_vector (default_constuct);
+        std::cout << "default construct = " << default_constuct << std::endl;
+    }
+};
+template <class MC>
+struct default_construct<boost::numeric::ublas::matrix_container<MC> >
+{
+    static void test ()
+    {
+        MC default_constuct;
+        initialize_vector (default_constuct);
+        std::cout << "default construct = " << default_constuct << std::endl;
+    }
+};
+
+/*
+ * Initialise test values in vector/matrix
+ */
+
+template<class V>
+void initialize_vector (V &v) {
+    typename V::size_type size = v.size ();
+    for (typename V::size_type i = 0; i < size; ++ i)
+        v [i] = typename V::value_type ( i + 1.f );
+}
+
+template<class M>
+void initialize_matrix_impl (M &m, ublas::packed_proxy_tag) {
+    typename M::size_type size1 = m.size1 ();
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+    for (typename M::iterator1 i = m.begin1(); i != m.end1(); ++ i)
+        for (typename M::iterator2 j = i.begin(); j != i.end(); ++ j)
+            *j = typename M::value_type ( i.index1() * size1 + j.index2() + 1.f );
+#else
+    for (typename M::iterator1 i = m.begin1(); i != m.end1(); ++ i)
+        for (typename M::iterator2 j = ublas::begin (i, ublas::iterator1_tag ()); j != ublas::end (i, ublas::iterator1_tag ()); ++ j)
+            *j = typename M::value_type ( i.index1() * size1 + j.index2() + 1.f );
+#endif
+}
+
+template<class M>
+void initialize_matrix_impl (M &m, ublas::sparse_proxy_tag) {
+    typename M::size_type size1 = m.size1 ();
+    typename M::size_type size2 = m.size2 ();
+    for (typename M::size_type i = 0; i < size1; ++ i)
+        for (typename M::size_type j = 0; j < size2; ++ j)
+            m (i, j) = typename M::value_type (i * size1 + j + 1.f);
+}
+
+template<class M>
+void initialize_matrix (M &m) {
+    initialize_matrix_impl (m, typename M::storage_category());
+}
+
+template<class M>
+void initialize_matrix (M &m, ublas::lower_tag) {
+    typename M::size_type size1 = m.size1 ();
+    typename M::size_type size2 = m.size2 ();
+    for (typename M::size_type i = 0; i < size1; ++ i) {
+        typename M::size_type j = 0;
+        for (; j <= i; ++ j)
+            m (i, j) = i * size1 + j + 1.f;
+        for (; j < size2; ++ j)
+            m (i, j) = 0.f;
+    }
+}
+template<class M>
+void initialize_matrix (M &m, ublas::upper_tag) {
+    typename M::size_type size1 = m.size1 ();
+    typename M::size_type size2 = m.size2 ();
+    for (typename M::size_type i = 0; i < size1; ++ i) {
+        typename M::size_type j = 0;
+        for (; j < i; ++ j)
+            m (i, j) = 0.f;
+        for (; j < size2; ++ j)
+            m (i, j) = i * size1 + j + 1.f;
+    }
+}
diff --git a/test/common/testhelper.hpp b/test/common/testhelper.hpp
new file mode 100644
index 0000000..b554511
--- /dev/null
+++ b/test/common/testhelper.hpp
@@ -0,0 +1,135 @@
+// Copyright 2008 Gunter Winkler <guwi17@gmx.de>
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef _HPP_TESTHELPER_
+#define _HPP_TESTHELPER_
+
+#include <utility>
+#include <iostream>
+#include <boost/numeric/ublas/vector_expression.hpp>
+#include <boost/numeric/ublas/matrix_expression.hpp>
+
+static unsigned _success_counter = 0;
+static unsigned _fail_counter    = 0;
+
+static inline
+void assertTrue(const char* message, bool condition) {
+#ifndef NOMESSAGES
+  std::cout << message;
+#endif
+  if ( condition ) {
+    ++ _success_counter;
+    std::cout << "1\n"; // success
+  } else {
+    ++ _fail_counter;
+    std::cout << "0\n"; // failed
+  }
+}
+
+template < class T >
+void assertEquals(const char* message, T expected, T actual) {
+#ifndef NOMESSAGES
+  std::cout << message;
+#endif
+  if ( expected == actual ) {
+    ++ _success_counter;
+    std::cout << "1\n"; // success
+  } else {
+    #ifndef NOMESSAGES
+      std::cout << " expected " << expected << " actual " << actual << " ";
+    #endif
+    ++ _fail_counter;
+    std::cout << "0\n"; // failed
+  }
+}
+
+inline static
+std::pair<unsigned, unsigned> getResults() {
+  return std::make_pair(_success_counter, _fail_counter);
+}
+
+template < class M1, class M2 >
+bool compare( const boost::numeric::ublas::matrix_expression<M1> & m1, 
+              const boost::numeric::ublas::matrix_expression<M2> & m2 ) {
+  if ((m1().size1() != m2().size1()) ||
+      (m1().size2() != m2().size2())) {
+    return false;
+  }
+
+  size_t size1 = m1().size1();
+  size_t size2 = m1().size2();
+  for (size_t i=0; i < size1; ++i) {
+    for (size_t j=0; j < size2; ++j) {
+      if ( m1()(i,j) != m2()(i,j) ) return false;
+    }
+  }
+  return true;
+}
+
+template < class M1, class M2 >
+bool compare( const boost::numeric::ublas::vector_expression<M1> & m1, 
+              const boost::numeric::ublas::vector_expression<M2> & m2 ) {
+  if (m1().size() != m2().size()) {
+    return false;
+  }
+
+  size_t size = m1().size();
+  for (size_t i=0; i < size; ++i) {
+    if ( m1()(i) != m2()(i) ) return false;
+  }
+  return true;
+}
+
+// Compare if two matrices or vectors are equals based on distance.
+
+template <class AE>
+typename AE::value_type mean_square(const boost::numeric::ublas::matrix_expression<AE> &me) {
+    typename AE::value_type s(0);
+    typename AE::size_type i, j;
+    for (i=0; i!= me().size1(); i++) {
+        for (j=0; j!= me().size2(); j++) {
+            s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(me()(i,j));
+        }
+    }
+    return s / (me().size1() * me().size2());
+}
+
+template <class AE>
+typename AE::value_type mean_square(const boost::numeric::ublas::vector_expression<AE> &ve) {
+    // We could have use norm2 here, but ublas' ABS does not support unsigned types.
+    typename AE::value_type s(0);
+    typename AE::size_type i;
+    for (i=0; i!= ve().size(); i++) {
+        s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(ve()(i));
+    }
+    return s / ve().size();
+}
+
+template < class M1, class M2 >
+bool compare_to( const boost::numeric::ublas::matrix_expression<M1> & m1,
+               const boost::numeric::ublas::matrix_expression<M2> & m2,
+               double tolerance = 0.0 ) {
+    if ((m1().size1() != m2().size1()) ||
+        (m1().size2() != m2().size2())) {
+        return false;
+    }
+
+    return mean_square(m2() - m1()) <= tolerance;
+}
+
+template < class M1, class M2 >
+bool compare_to( const boost::numeric::ublas::vector_expression<M1> & m1,
+               const boost::numeric::ublas::vector_expression<M2> & m2,
+               double tolerance = 0.0 ) {
+    if (m1().size() != m2().size()) {
+        return false;
+    }
+
+    return mean_square(m2() - m1()) <= tolerance;
+}
+
+
+#endif
diff --git a/test/comp_mat_erase.cpp b/test/comp_mat_erase.cpp
new file mode 100644
index 0000000..7001890
--- /dev/null
+++ b/test/comp_mat_erase.cpp
@@ -0,0 +1,106 @@
+//  Copyright (c) 2011 David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+
+#define BOOST_TEST_MODULE SparseMatrixErasureTest
+#include <boost/test/included/unit_test.hpp>
+
+
+BOOST_AUTO_TEST_CASE( compressed_matrix_erase_after_end )
+{
+    boost::numeric::ublas::compressed_matrix<int, boost::numeric::ublas::row_major > A(2, 2);
+
+    BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 1 );
+    BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 );
+
+    A(0,0) = 1;
+
+    BOOST_CHECK_EQUAL( A.nnz(), (std::size_t) 1 );
+    BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 );
+
+    // check new element
+    BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.value_data()[0], 1 );
+    // check end of list marker
+    BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 );
+
+    A.erase_element(1,0);
+
+    BOOST_CHECK_EQUAL( A.nnz(), (std::size_t) 1 );
+    BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 );
+    BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 1 );
+
+    // check new element
+    BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.value_data()[0], 1 );
+    // check end of list marker
+    BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 );
+
+    A.erase_element(0,0);
+
+    BOOST_CHECK_EQUAL( A.nnz(), (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 );
+    BOOST_CHECK_EQUAL( A.filled2(),(std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 );
+
+}
+
+BOOST_AUTO_TEST_CASE( compressed_matrix_erase_in_the_middle )
+{
+    boost::numeric::ublas::compressed_matrix<int, boost::numeric::ublas::row_major > A(2, 2);
+
+    BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 1 );
+    BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 );
+
+    A.insert_element(0,1,5);
+
+    BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 );
+    BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 1 );
+
+    // check new element
+    BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 1 );
+    BOOST_CHECK_EQUAL( A.value_data()[0], 5 );
+    // check end of list marker
+    BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 );
+
+    A.insert_element(0,0,4);
+
+    BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 );
+    BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 2 );
+
+    // check new element
+    BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.value_data()[0], 4 );
+    // check previous element
+    BOOST_CHECK_EQUAL( A.index2_data()[1], (std::size_t) 1 );
+    BOOST_CHECK_EQUAL( A.value_data()[1], 5 );
+    // check end of list marker
+    BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 2 );
+
+    A.erase_element(0,0);
+
+    BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 );
+    BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 1 );
+
+    BOOST_CHECK_EQUAL( A.index2_data()[0], (std::size_t) 1 );
+    BOOST_CHECK_EQUAL( A.value_data()[0], 5 );
+
+    BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 1 );
+
+    A.erase_element(0,1);
+
+    BOOST_CHECK_EQUAL( A.filled1(), (std::size_t) 2 );
+    BOOST_CHECK_EQUAL( A.filled2(), (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.index1_data()[0], (std::size_t) 0 );
+    BOOST_CHECK_EQUAL( A.index1_data()[1], (std::size_t) 0 );
+
+}
diff --git a/test/concepts.cpp b/test/concepts.cpp
new file mode 100644
index 0000000..ba98129
--- /dev/null
+++ b/test/concepts.cpp
@@ -0,0 +1,34 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/banded.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/symmetric.hpp>
+#include <boost/numeric/ublas/hermitian.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/vector_of_vector.hpp>
+#include <boost/numeric/ublas/detail/concepts.hpp>
+#include <boost/numeric/ublas/experimental/sparse_view.hpp>
+//#include <boost/numeric/ublas/vector_view.hpp>
+
+namespace ublas = boost::numeric::ublas;
+
+
+int main () {
+    void (* check) (void) = ublas::concept_checks;
+    boost::ignore_unused_variable_warning (check);
+}
diff --git a/test/manual/Jamfile.v2 b/test/manual/Jamfile.v2
new file mode 100644
index 0000000..5ef982d
--- /dev/null
+++ b/test/manual/Jamfile.v2
@@ -0,0 +1,8 @@
+# Copyright (c) 2006 Michael Stevens
+# Use, modification and distribution are subject to the
+# Boost Software License, Version 1.0. (See accompanying file
+# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+exe sp_resize : sp_resize.cpp ;
+
+exe test_move_semantics : test_move_semantics.cpp ;
diff --git a/test/manual/sp_resize.cpp b/test/manual/sp_resize.cpp
new file mode 100644
index 0000000..2d52dbb
--- /dev/null
+++ b/test/manual/sp_resize.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2006 Michael Stevens
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include <iostream>
+
+#include <boost/numeric/ublas/vector_sparse.hpp>
+
+typedef double Real;
+
+template <class V>
+void printV(const V& v) {
+  std::cout << "size: " << v.size() << " nnz_capacity: " << v.nnz_capacity() << " nnz: " << v.nnz() << std::endl;
+  for (typename V::const_iterator i = v.begin(); i != v.end(); i++) {
+    std::cout << i.index() << ":" << (*i) << "  ";
+  }
+  std::cout << std::endl;
+}
+
+template <class V>
+void run_test()
+{
+  V v(10);
+
+  v[0] = 1;
+  v[5] = 1;
+  v[8] = 1;
+  v[9] = 1;
+
+  printV(v);
+
+  v.resize(9); printV(v);
+  v.resize(12); printV(v);
+  v.resize(2); printV(v);
+  v.resize(0); printV(v);
+
+  v.resize(5); v[0] = 1; printV(v);
+  v.resize(5,false); printV(v);
+}
+
+int main(int, char **) {
+
+  std::cout << "---- MAPPED ----\n";
+  run_test< boost::numeric::ublas::mapped_vector<Real> >();
+  std::cout << "---- COMPRESSED ----\n";
+  run_test< boost::numeric::ublas::compressed_vector<Real> >();
+  std::cout << "---- COORDINATE ----\n";
+  run_test< boost::numeric::ublas::coordinate_vector<Real> >();
+
+  return 0;
+}
+
diff --git a/test/manual/test_move_semantics.cpp b/test/manual/test_move_semantics.cpp
new file mode 100644
index 0000000..188491e
--- /dev/null
+++ b/test/manual/test_move_semantics.cpp
@@ -0,0 +1,127 @@
+/** test move semantics - run with and without BOOST_UBLAS_MOVE_SEMANTICS defined */
+
+//          Copyright Nasos Iliopoulos, Gunter Winkler 2009.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_UBLAS_MOVE_SEMANTICS
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+namespace ublas= boost::numeric::ublas;
+std::vector<double> a;
+
+ublas::vector<double> doubleit(ublas::vector<double> m)
+{
+    ublas::vector<double> r;
+    r=2.0*m;
+    std::cout << "Temporary pointer: " << &r[0] << std::endl;
+    return r;
+}
+template <class T,size_t N>
+ublas::bounded_vector<T,N > doubleit(ublas::bounded_vector<T, N> m)
+{
+    ublas::bounded_vector<T,N> r;
+    r=2.0*m;
+    std::cout << "Temporary pointer: " << &r[0] << std::endl;
+    return r;
+}
+
+template <class T,size_t N>
+ublas::c_vector<T,N > doubleit(ublas::c_vector<T, N> m)
+{
+    ublas::c_vector<T,N> r;
+    r=2.0*m;
+    std::cout << "Temporary pointer: " << &r[0] << std::endl;
+    return r;
+}
+
+ublas::matrix<double> doubleit(ublas::matrix<double> m)
+{
+    ublas::matrix<double> r;
+    r=2.0*m;
+    std::cout << "Temporary pointer r: " << &r(0,0) << std::endl;
+    return r;
+}
+template <class T,size_t N, size_t M>
+ublas::bounded_matrix<T,N, M > doubleit(ublas::bounded_matrix<T, N, M> m)
+{
+    ublas::bounded_matrix<T,N, M> r;
+    r=2.0*m;
+    std::cout << "Temporary pointer: " <<  &(r(0,0)) << std::endl;
+    return r;
+}
+
+template <class T,size_t N, size_t M>
+ublas::c_matrix<T,N, M > doubleit(ublas::c_matrix<T, N, M> m)
+{
+    ublas::c_matrix<T,N, M> r;
+    r=2.0*m;
+    std::cout << "Temporary pointer: " << &(r(0,0)) << std::endl;
+    return r;
+}
+
+
+void test1()
+{
+    std::cout << "vector<double> --------------------------------------------------------------------" << std::endl;
+    ublas::vector<double> a(ublas::scalar_vector<double>(2,2.0));
+    a = doubleit(a);
+    std::cout << "Pointer (must be equal to temp. pointer if move semantics are enabled) : " << &a[0] << std::endl;
+
+    std::cout << a << std::endl;
+
+    std::cout << "bounded_vector<double,2> --------------------------------------------------------------------" << std::endl;
+    ublas::bounded_vector<double,2> b(ublas::scalar_vector<double>(2,2.0));
+    ublas::bounded_vector<double,2> c;
+    noalias(c)=doubleit(b);
+    std::cout << "Pointer (bounded_vector swaps by copy this should be different than temp. pointer) : " << &c[0] << std::endl;
+    c(1)=0.0;
+    std::cout << b << std::endl;
+    std::cout << c << std::endl;
+
+    std::cout << "c_vector<double,2> --------------------------------------------------------------------" << std::endl;
+    ublas::c_vector<double,2> e=ublas::scalar_vector<double>(2,2.0);
+    ublas::c_vector<double,2> f;
+    f=doubleit(e);
+    std::cout << "Pointer (c_vector swaps by copy this should be different than temp. pointer) : " << &f[0] << std::endl;
+    f(1)=0;
+    std::cout << e << std::endl;
+    std::cout << f << std::endl;
+
+}
+
+void test2() {
+    std::cout << "matrix<double> --------------------------------------------------------------------" << std::endl;
+    ublas::matrix<double> a(ublas::scalar_matrix<double>(2, 3, 2.0));
+    a = doubleit(a);
+    std::cout << "Pointer (must be equal to temp. pointer if move semantics are enabled) : " << &(a(0,0)) << std::endl;
+    std::cout << a << std::endl;
+
+    std::cout << "bounded_matrix<double,2, 3> --------------------------------------------------------------------" << std::endl;
+    ublas::bounded_matrix<double,2, 3> b(ublas::scalar_matrix<double>(2,3, 2.0));
+    ublas::bounded_matrix<double,2, 3> c;
+    noalias(c)=doubleit(b);
+    std::cout << "Pointer (bounded_matrix swaps by copy this should be different than temp. pointer) : " << &(c(0,0)) << std::endl;
+    c(1,1)=0.0;
+    std::cout << b << std::endl;
+    std::cout << c << std::endl;
+
+    std::cout << "c_matrix<double,2 ,3> --------------------------------------------------------------------" << std::endl;
+    ublas::c_matrix<double,2, 3> e=ublas::scalar_matrix<double>(2,3, 2.0);
+    ublas::c_matrix<double,2, 3> f;
+    f=doubleit(e);
+    std::cout << "Pointer (c_matrix swaps by copy this should be different than temp. pointer) : " << &(f(0,0)) << std::endl;
+    f(1,1)=0;
+    std::cout << e << std::endl;
+    std::cout << f << std::endl;
+}
+
+int main(){
+    test1();
+    test2();
+    return 0;
+}
+
diff --git a/test/num_columns.cpp b/test/num_columns.cpp
new file mode 100644
index 0000000..68c9770
--- /dev/null
+++ b/test/num_columns.cpp
@@ -0,0 +1,110 @@
+//  Copyright (c) 2011 David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/numeric/ublas/fwd.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_expression.hpp>
+#include <boost/numeric/ublas/operation/num_columns.hpp>
+#include <iostream>
+#include "utils.hpp"
+
+
+BOOST_UBLAS_TEST_DEF( test_row_major_matrix_container )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Container" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    BOOST_UBLAS_DEBUG_TRACE( "num_columns(A) = " << boost::numeric::ublas::num_columns(A) << " ==> " << A.size2() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(A) == A.size2() );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_col_major_matrix_container )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Container" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    BOOST_UBLAS_DEBUG_TRACE( "num_columns(A) = " << boost::numeric::ublas::num_columns(A) << " ==> " << A.size2() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(A) == A.size2() );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_matrix_expression )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Expression" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type> matrix_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    BOOST_UBLAS_DEBUG_TRACE( "num_columns(A') = " << boost::numeric::ublas::num_columns(boost::numeric::ublas::trans(A)) << " ==> " << boost::numeric::ublas::trans(A).size2() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(boost::numeric::ublas::trans(A)) == boost::numeric::ublas::trans(A).size2() );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_matrix_reference )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Reference" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type> matrix_type;
+    typedef boost::numeric::ublas::matrix_reference<matrix_type> matrix_reference_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    BOOST_UBLAS_DEBUG_TRACE( "num_columns(reference(A)) = " << boost::numeric::ublas::num_columns(matrix_reference_type(A)) << " ==> " << matrix_reference_type(A).size2() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_columns(matrix_reference_type(A)) == matrix_reference_type(A).size2() );
+}
+
+
+int main()
+{
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_row_major_matrix_container );
+    BOOST_UBLAS_TEST_DO( test_col_major_matrix_container );
+    BOOST_UBLAS_TEST_DO( test_matrix_expression );
+    BOOST_UBLAS_TEST_DO( test_matrix_reference );
+
+    BOOST_UBLAS_TEST_END();
+}
diff --git a/test/num_rows.cpp b/test/num_rows.cpp
new file mode 100644
index 0000000..1e3a1e7
--- /dev/null
+++ b/test/num_rows.cpp
@@ -0,0 +1,110 @@
+//  Copyright (c) 2011 David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/numeric/ublas/fwd.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_expression.hpp>
+#include <boost/numeric/ublas/operation/num_rows.hpp>
+#include <iostream>
+#include "utils.hpp"
+
+
+BOOST_UBLAS_TEST_DEF( test_row_major_matrix_container )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Container" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    BOOST_UBLAS_DEBUG_TRACE( "num_rows(A) = " << boost::numeric::ublas::num_rows(A) << " ==> " << A.size1() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(A) == A.size1() );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_col_major_matrix_container )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Container" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    BOOST_UBLAS_DEBUG_TRACE( "num_rows(A) = " << boost::numeric::ublas::num_rows(A) << " ==> " << A.size1() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(A) == A.size1() );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_matrix_expression )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Expression" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type> matrix_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    BOOST_UBLAS_DEBUG_TRACE( "num_rows(A') = " << boost::numeric::ublas::num_rows(boost::numeric::ublas::trans(A)) << " ==> " << boost::numeric::ublas::trans(A).size1() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(boost::numeric::ublas::trans(A)) == boost::numeric::ublas::trans(A).size1() );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_matrix_reference )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Reference" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type> matrix_type;
+    typedef boost::numeric::ublas::matrix_reference<matrix_type> matrix_reference_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    BOOST_UBLAS_DEBUG_TRACE( "num_rows(reference(A)) = " << boost::numeric::ublas::num_rows(matrix_reference_type(A)) << " ==> " << matrix_reference_type(A).size1() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::num_rows(matrix_reference_type(A)) == matrix_reference_type(A).size1() );
+}
+
+
+int main()
+{
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_row_major_matrix_container );
+    BOOST_UBLAS_TEST_DO( test_col_major_matrix_container );
+    BOOST_UBLAS_TEST_DO( test_matrix_expression );
+    BOOST_UBLAS_TEST_DO( test_matrix_reference );
+
+    BOOST_UBLAS_TEST_END();
+}
diff --git a/test/placement_new.cpp b/test/placement_new.cpp
new file mode 100644
index 0000000..940da7d
--- /dev/null
+++ b/test/placement_new.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2004 Michael Stevens
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*
+ * Test placement new and array placement new for uBLAS
+ *  See if base pointer is effected by array count cookie
+ */
+
+#include <boost/numeric/ublas/storage.hpp>
+#include <iostream>
+#include <new>
+
+// User defined type to capture base pointer on construction
+
+class udt {
+public:
+    udt () {
+       base_pointer = this;
+    }
+    ~udt () {}      // required for GCC prior to 3.4 to generate cookie
+
+    static udt* base_pointer;
+};
+
+udt* udt::base_pointer;
+
+int main ()
+{
+    udt a;
+    udt* ap = &a;
+
+    // Capture placement new offsets for a udt    
+    new (ap) udt;
+    int new_offset = int (udt::base_pointer - ap);
+    new (ap) udt [1];
+    int array_new_offset = int (udt::base_pointer - ap);
+    
+    // Print offsets - we expect 0,0 or 0,sizeof(std::size_t)
+    std::cout << new_offset <<','<< array_new_offset << std::endl;
+
+    // Return status
+    if (new_offset != 0)
+        return -1;          // Very bad if new has an offset
+
+#ifdef BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
+    bool expect_array_offset = false;
+#else
+    bool expect_array_offset = true;
+#endif
+        // Check match between config and array
+    if (!expect_array_offset && array_new_offset != 0) {
+        return -2;          // Bad config should not enable array new
+    }
+    if (expect_array_offset && array_new_offset == 0) {
+        return -3;          // Config could enable array new
+    }
+
+    return 0;
+}
diff --git a/test/size.cpp b/test/size.cpp
new file mode 100644
index 0000000..1fd2f9d
--- /dev/null
+++ b/test/size.cpp
@@ -0,0 +1,275 @@
+//  Copyright (c) 2011 David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/numeric/ublas/fwd.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_expression.hpp>
+#include <boost/numeric/ublas/operation/size.hpp>
+#include <boost/numeric/ublas/tags.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_expression.hpp>
+#include <iostream>
+#include "utils.hpp"
+
+
+BOOST_UBLAS_TEST_DEF( test_vector_container )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Container" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::vector<value_type> vector_type;
+
+    vector_type v(5);
+
+    v(0) = 0.555950;
+    v(1) = 0.108929;
+    v(2) = 0.948014;
+    v(3) = 0.023787;
+    v(4) = 1.023787;
+
+
+    // size(v)
+    BOOST_UBLAS_DEBUG_TRACE( "size(v) = " << boost::numeric::ublas::size(v) << " ==> " << v.size() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(v) == v.size() );
+
+    // size<1>(v)
+    BOOST_UBLAS_DEBUG_TRACE( "size<1>(v) = " << (boost::numeric::ublas::size<1>(v)) << " ==> " << v.size() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(v) == v.size()) );
+
+    // [NOT_COMPILE]: this should *correctly* cause a compilation error
+    // size<2>(v)
+    //BOOST_UBLAS_DEBUG_TRACE( "size<2>(v) = " << (boost::numeric::ublas::size<vector_type,2>(v)) << " ==> " << v.size() );
+    //BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(v) == v.size()) );
+    // [/NOT_COMPILE]
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_vector_expression )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Expression" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::vector<value_type> vector_type;
+
+    vector_type v(5);
+
+    v(0) = 0.555950;
+    v(1) = 0.108929;
+    v(2) = 0.948014;
+    v(3) = 0.023787;
+    v(4) = 1.023787;
+
+
+    // size(-v)
+    BOOST_UBLAS_DEBUG_TRACE( "size(-v) = " << boost::numeric::ublas::size(-v) << " ==> " << (-v).size() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(-v) == (-v).size() );
+
+    // size<1>(-v)
+    BOOST_UBLAS_DEBUG_TRACE( "size<1>(-v) = " << (boost::numeric::ublas::size<1>(-v)) << " ==> " << (-v).size() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(-v) == (-v).size()) );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_vector_reference )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Vector Reference" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::vector<value_type> vector_type;
+    typedef boost::numeric::ublas::vector_reference<vector_type> vector_reference_type;
+
+    vector_type v(5);
+
+    v(0) = 0.555950;
+    v(1) = 0.108929;
+    v(2) = 0.948014;
+    v(3) = 0.023787;
+    v(4) = 1.023787;
+
+
+    // size(reference(v)
+    BOOST_UBLAS_DEBUG_TRACE( "size(reference(v)) = " << boost::numeric::ublas::size(vector_reference_type(v)) << " ==> " << vector_reference_type(v).size() );
+    BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(vector_reference_type(v)) == vector_reference_type(v).size() );
+
+    // size<1>(reference(v))
+    BOOST_UBLAS_DEBUG_TRACE( "size<1>(reference(v)) = " << (boost::numeric::ublas::size<1>(vector_reference_type(v))) << " ==> " << vector_reference_type(v).size() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(vector_reference_type(v)) == vector_reference_type(v).size()) );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_row_major_matrix_container )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Row-major Matrix Container" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::row_major> matrix_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    // [NOT_COMPILE]
+    // size(A)
+    //BOOST_UBLAS_DEBUG_TRACE( "size(A) = " << boost::numeric::ublas::size(A) << " ==> " << A.size1() );
+    //BOOST_UBLAS_TEST_CHECK( boost::numeric::ublas::size(A) == A.size1() );
+    // [/NOT_COMPILE]
+
+    // size<1>(A)
+    BOOST_UBLAS_DEBUG_TRACE( "size<1>(A) = " << (boost::numeric::ublas::size<1>(A)) << " ==> " << A.size1() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(A) == A.size1()) );
+
+    // size<2>(A)
+    BOOST_UBLAS_DEBUG_TRACE( "size<2>(A) = " << (boost::numeric::ublas::size<2>(A)) << " ==> " << A.size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(A) == A.size2()) );
+
+    // size<major>(A)
+    BOOST_UBLAS_DEBUG_TRACE( "size<major>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A)) << " ==> " << A.size1() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A) == A.size1()) );
+
+    // size<minor>(A)
+    BOOST_UBLAS_DEBUG_TRACE( "size<minor>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A)) << " ==> " << A.size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A) == A.size2()) );
+
+    // size<leading>(A)
+    BOOST_UBLAS_DEBUG_TRACE( "size<leading>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A)) << " ==> " << A.size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A) == A.size2()) );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_col_major_matrix_container )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Column-major Matrix Container" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type, boost::numeric::ublas::column_major> matrix_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    // size<1>(A)
+    BOOST_UBLAS_DEBUG_TRACE( "size<1>(A) = " << (boost::numeric::ublas::size<1>(A)) << " ==> " << A.size1() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(A) == A.size1()) );
+
+    // size<2>(A)
+    BOOST_UBLAS_DEBUG_TRACE( "size<2>(A) = " << (boost::numeric::ublas::size<2>(A)) << " ==> " << A.size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(A) == A.size2()) );
+
+    // size<major>(A)
+    BOOST_UBLAS_DEBUG_TRACE( "size<major>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A)) << " ==> " << A.size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(A) == A.size2()) );
+
+    // size<minor>(A)
+    BOOST_UBLAS_DEBUG_TRACE( "size<minor>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A)) << " ==> " << A.size1() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(A) == A.size1()) );
+
+    // size<leading>(A)
+    BOOST_UBLAS_DEBUG_TRACE( "size<leading>(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A)) << " ==> " << A.size1() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(A) == A.size1()) );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_matrix_expression )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Expression" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type> matrix_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    // size<1>(A')
+    BOOST_UBLAS_DEBUG_TRACE( "size<1>(A') = " << (boost::numeric::ublas::size<1>(boost::numeric::ublas::trans(A))) << " ==> " << A.size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(boost::numeric::ublas::trans(A)) == A.size2()) );
+
+    // size<2>(A')
+    BOOST_UBLAS_DEBUG_TRACE( "size<2>(A') = " << (boost::numeric::ublas::size<2>(boost::numeric::ublas::trans(A))) << " ==> " << A.size1() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(boost::numeric::ublas::trans(A)) == A.size1()) );
+
+    // size<major>(A') [A is row-major => A' column-major, and viceversa]
+    BOOST_UBLAS_DEBUG_TRACE( "size<major>(A') = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(boost::numeric::ublas::trans(A))) << " ==> " << A.size1() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(boost::numeric::ublas::trans(A)) == A.size1()) );
+
+    // size<minor>(A')  [A is row-major => A' column-major, and viceversa]
+    BOOST_UBLAS_DEBUG_TRACE( "size<minor>(A') = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(boost::numeric::ublas::trans(A))) << " ==> " << A.size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(boost::numeric::ublas::trans(A)) == A.size2()) );
+
+    // size<leading>(A')  [A row-major => A' column-major, and viceversa]
+    BOOST_UBLAS_DEBUG_TRACE( "size<leading>(A') = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(boost::numeric::ublas::trans(A))) << " ==> " << A.size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(boost::numeric::ublas::trans(A)) == A.size2()) );
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_matrix_reference )
+{
+    BOOST_UBLAS_DEBUG_TRACE( "TEST Matrix Reference" );
+
+    typedef double value_type;
+    typedef boost::numeric::ublas::matrix<value_type> matrix_type;
+    typedef boost::numeric::ublas::matrix_reference<matrix_type> matrix_reference_type;
+
+    matrix_type A(5,4);
+
+    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
+    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
+    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
+    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
+    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;
+
+
+    // size<1>(reference(A))
+    BOOST_UBLAS_DEBUG_TRACE( "size<1>(reference(A)) = " << (boost::numeric::ublas::size<1>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size1() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<1>(matrix_reference_type(A)) == matrix_reference_type(A).size1()) );
+
+    // size<2>(reference(A))
+    BOOST_UBLAS_DEBUG_TRACE( "size<2>(reference(A)) = " << (boost::numeric::ublas::size<2>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<2>(matrix_reference_type(A)) == matrix_reference_type(A).size2()) );
+
+    // size<major>(reference(A))
+    BOOST_UBLAS_DEBUG_TRACE( "size<major>(reference(A) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size1() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::major>(matrix_reference_type(A)) == matrix_reference_type(A).size1()) );
+
+    // size<minor>(reference(A))
+    BOOST_UBLAS_DEBUG_TRACE( "size<minor>(reference(A)) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::minor>(matrix_reference_type(A)) == matrix_reference_type(A).size2()) );
+
+    // size<leading>(reference(A))
+    BOOST_UBLAS_DEBUG_TRACE( "size<leading>(reference(A)) = " << (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(matrix_reference_type(A))) << " ==> " << matrix_reference_type(A).size2() );
+    BOOST_UBLAS_TEST_CHECK( (boost::numeric::ublas::size<boost::numeric::ublas::tag::leading>(matrix_reference_type(A)) == matrix_reference_type(A).size2()) );
+}
+
+
+int main()
+{
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_vector_container );
+    BOOST_UBLAS_TEST_DO( test_vector_expression );
+    BOOST_UBLAS_TEST_DO( test_vector_reference );
+    BOOST_UBLAS_TEST_DO( test_row_major_matrix_container );
+    BOOST_UBLAS_TEST_DO( test_col_major_matrix_container );
+    BOOST_UBLAS_TEST_DO( test_matrix_expression );
+    BOOST_UBLAS_TEST_DO( test_matrix_reference );
+
+    BOOST_UBLAS_TEST_END();
+}
diff --git a/test/sparse_view_test.cpp b/test/sparse_view_test.cpp
new file mode 100644
index 0000000..178e444
--- /dev/null
+++ b/test/sparse_view_test.cpp
@@ -0,0 +1,106 @@
+//  Copyright (c) 2009-2011 Gunter Winkler, David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// ublas headers
+
+#include <boost/numeric/ublas/experimental/sparse_view.hpp>
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+#include <boost/numeric/ublas/traits/c_array.hpp>
+
+// other boost headers
+
+// headers for testcase
+
+#define BOOST_TEST_MODULE SparseMatrixErasureTest
+#include <boost/test/included/unit_test.hpp>
+
+// standard and system headers
+
+#include <iostream>
+#include <string>
+
+namespace ublas = boost::numeric::ublas;
+
+    /*
+      sparse input matrix:
+
+      1 2 0 0
+      0 3 9 0
+      0 1 4 0
+    */
+
+    static const std::string inputMatrix = "[3,4]((1,2,0,0),(0,3,9,0),(0,1,4,0))\n";
+
+    const unsigned int NNZ  = 6;
+    const unsigned int IB   = 1;
+    const double VA[]       = { 1.0, 2.0, 3.0, 9.0, 1.0, 4.0 };
+    const unsigned int IA[] = { 1, 3, 5, 7 };
+    const unsigned int JA[] = { 1, 2, 2, 3, 2, 3 };
+
+BOOST_AUTO_TEST_CASE( test_construction_and_basic_operations )
+{
+
+    typedef ublas::matrix<double> DENSE_MATRIX;
+    
+    // prepare data
+
+    DENSE_MATRIX A;
+
+    std::istringstream iss(inputMatrix);
+    iss >> A;
+
+    std::cout << A << std::endl;
+
+    std::cout << ( ublas::make_compressed_matrix_view<ublas::row_major,IB>(3,4,NNZ,IA,JA,VA) ) << std::endl;
+
+    typedef ublas::compressed_matrix_view<ublas::row_major, IB, unsigned int [4], unsigned int [NNZ], double[NNZ]> COMPMATVIEW;
+
+    COMPMATVIEW viewA(3,4,NNZ,IA,JA,VA);
+
+    std::cout << viewA << std::endl;
+
+}
+
+
+
+BOOST_AUTO_TEST_CASE( test_construction_from_pointers )
+{
+
+    std::cout << ( ublas::make_compressed_matrix_view<ublas::column_major,IB>(4,3,NNZ
+                                                                              , ublas::c_array_view<const unsigned int>(4,&(IA[0]))
+                                                                              , ublas::c_array_view<const unsigned int>(6,&(JA[0]))
+                                                                              , ublas::c_array_view<const double>(6,&(VA[0]))) ) << std::endl;
+
+    unsigned int * ia = new unsigned int[4]();
+    unsigned int * ja = new unsigned int[6]();
+    double * va = new double[6]();
+
+    std::copy(&(IA[0]),&(IA[4]),ia);
+    std::copy(&(JA[0]),&(JA[6]),ja);
+    std::copy(&(VA[0]),&(VA[6]),va);
+
+    typedef ublas::compressed_matrix_view<ublas::column_major
+      , IB
+      , ublas::c_array_view<unsigned int>
+      , ublas::c_array_view<unsigned int>
+      , ublas::c_array_view<double> > COMPMATVIEW;
+
+    COMPMATVIEW viewA(4,3,NNZ
+                      , ublas::c_array_view<unsigned int>(4,ia)
+                      , ublas::c_array_view<unsigned int>(6,ja)
+                      , ublas::c_array_view<double>(6,va));
+
+    std::cout << viewA << std::endl;
+
+    delete[] va;
+    delete[] ja;
+    delete[] ia;
+
+}
diff --git a/test/test1.cpp b/test/test1.cpp
new file mode 100644
index 0000000..53de790
--- /dev/null
+++ b/test/test1.cpp
@@ -0,0 +1,20 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test1.hpp"
+
+int main () {
+    test_vector ();
+    test_matrix_vector ();
+    test_matrix ();
+    return 0;
+}
diff --git a/test/test1.hpp b/test/test1.hpp
new file mode 100644
index 0000000..fcf3d67
--- /dev/null
+++ b/test/test1.hpp
@@ -0,0 +1,33 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef TEST1_H
+#define TEST1_H
+
+#include <iostream>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+namespace ublas = boost::numeric::ublas;
+
+#include "common/init.hpp"
+
+void test_vector ();
+void test_matrix_vector ();
+void test_matrix ();
+
+
+#endif
diff --git a/test/test11.cpp b/test/test11.cpp
new file mode 100644
index 0000000..2d3d275
--- /dev/null
+++ b/test/test11.cpp
@@ -0,0 +1,265 @@
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+
+#include "test1.hpp"
+
+// Test vector expression templates
+template<class V, int N>
+struct test_my_vector {
+    typedef typename V::value_type value_type;
+    typedef typename V::size_type size_type;
+    typedef typename ublas::type_traits<value_type>::real_type real_type;
+
+    template<class VP>
+    void test_container_with (VP &v1) const {
+        // Container type tests in addition to expression types
+        // Insert and erase
+        v1.insert_element (0, 55);
+        v1.erase_element (1);
+        v1.clear ();
+    }
+    
+    template<class VP>
+    void test_expression_with (VP &v1, VP &v2, VP &v3) const {
+        // Expression type tests
+        value_type t;
+        size_type i;
+        real_type n;
+
+        // Default Construct
+        default_construct<VP>::test ();
+        
+        // Copy and swap
+        initialize_vector (v1);
+        initialize_vector (v2);
+        v1 = v2;
+        std::cout << "v1 = v2 = " << v1 << std::endl;
+        v1.assign_temporary (v2);
+        std::cout << "v1.assign_temporary (v2) = " << v1 << std::endl;
+        v1.swap (v2);
+        std::cout << "v1.swap (v2) = " << v1 << " " << v2 << std::endl;
+        
+        // Zero assignment
+        v1 = ublas::zero_vector<> (v1.size ());
+        std::cout << "v1.zero_vector = " << v1 << std::endl;
+        v1 = v2;
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+            // Project range and slice
+        initialize_vector (v1);
+        initialize_vector (v2);
+        project (v1, ublas::range(0,1)) = project (v2, ublas::range(0,1));
+        project (v1, ublas::range(0,1)) = project (v2, ublas::slice(0,1,1));
+        project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::slice(0,1,2));
+        project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::range(0,2));
+        std::cout << "v1 = range/slice " << v1 << std::endl;
+#endif
+
+            // Unary vector operations resulting in a vector
+        initialize_vector (v1);
+        v2 = - v1;
+        std::cout << "- v1 = " << v2 << std::endl;
+        v2 = ublas::conj (v1);
+        std::cout << "conj (v1) = " << v2 << std::endl;
+
+        // Binary vector operations resulting in a vector
+        initialize_vector (v1);
+        initialize_vector (v2);
+        v3 = v1 + v2;
+        std::cout << "v1 + v2 = " << v3 << std::endl;
+        v3 = v1 - v2;
+        std::cout << "v1 - v2 = " << v3 << std::endl;
+        v3 = ublas::element_prod (v1, v2);
+        std::cout << "element_prod (v1, v2) = " << v3 << std::endl;
+
+        // Scaling a vector
+        t = N;
+        initialize_vector (v1);
+        v2 = value_type (1.) * v1;
+        std::cout << "1. * v1 = " << v2 << std::endl;
+        v2 = t * v1;
+        std::cout << "N * v1 = " << v2 << std::endl;
+        initialize_vector (v1);
+        v2 = v1 * value_type (1.);
+        std::cout << "v1 * 1. = " << v2 << std::endl;
+        v2 = v1 * t;
+	  std::cout << "v1 * value_type(N) = " << v2 << std::endl;
+	  // test interop with integer
+	  v2 = v1 * N;
+
+        std::cout << "v1 * N = " << v2 << std::endl;
+
+        // Some assignments
+        initialize_vector (v1);
+        initialize_vector (v2);
+        v2 += v1;
+        std::cout << "v2 += v1 = " << v2 << std::endl;
+        v2 -= v1;
+        std::cout << "v2 -= v1 = " << v2 << std::endl;
+        v2 = v2 + v1;
+        std::cout << "v2 = v2 + v1 = " << v2 << std::endl;
+        v2 = v2 - v1;
+        std::cout << "v2 = v2 - v1 = " << v2 << std::endl;
+        v1 *= value_type (1.);
+        std::cout << "v1 *= 1. = " << v1 << std::endl;
+        v1 *= t;
+	  std::cout << "v1 *= value_type(N) = " << v1 << std::endl;
+	  // test interop with integer
+	  v1 *= N;
+        std::cout << "v1 *= N = " << v1 << std::endl;
+
+        // Unary vector operations resulting in a scalar
+        initialize_vector (v1);
+        t = ublas::sum (v1);
+        std::cout << "sum (v1) = " << t << std::endl;
+        n = ublas::norm_1 (v1);
+        std::cout << "norm_1 (v1) = " << n << std::endl;
+        n = ublas::norm_2 (v1);
+        std::cout << "norm_2 (v1) = " << n << std::endl;
+        n = ublas::norm_inf (v1);
+        std::cout << "norm_inf (v1) = " << n << std::endl;
+
+        i = ublas::index_norm_inf (v1);
+        std::cout << "index_norm_inf (v1) = " << i << std::endl;
+
+        // Binary vector operations resulting in a scalar
+        initialize_vector (v1);
+        initialize_vector (v2);
+        t = ublas::inner_prod (v1, v2);
+        std::cout << "inner_prod (v1, v2) = " << t << std::endl;
+
+        // Scalar and Binary vector expression resulting in a vector
+        initialize_vector (v1);
+        initialize_vector (v2);
+        v1 = v1 * ublas::inner_prod (v1, v2);
+        std::cout << "v1 * inner_prod (v1, v2) = " << v1 << std::endl;
+    }
+
+    void operator () () const {
+        V v1 (N), v2 (N), v3 (N);
+        test_expression_with (v1, v2, v3);
+        test_container_with (v1);
+
+#ifdef USE_RANGE
+        ublas::vector_range<V> vr1 (v1, ublas::range (0, N)),
+                               vr2 (v2, ublas::range (0, N)),
+                               vr3 (v3, ublas::range (0, N));
+        test_expression_with (vr1, vr2, vr3);
+#endif
+
+#ifdef USE_SLICE
+        ublas::vector_slice<V> vs1 (v1, ublas::slice (0, 1, N)),
+                               vs2 (v2, ublas::slice (0, 1, N)),
+                               vs3 (v3, ublas::slice (0, 1, N));
+        test_expression_with (vs1, vs2, vs3);
+#endif
+    }
+};
+
+// Test vector
+void test_vector () {
+    std::cout << "test_vector" << std::endl;
+
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_vector<ublas::vector<float, ublas::bounded_array<float, 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_vector<ublas::vector<double, ublas::bounded_array<double, 3> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_vector<ublas::vector<float, ublas::unbounded_array<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_vector<ublas::vector<double, ublas::unbounded_array<double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_vector<ublas::vector<float, std::vector<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_vector<ublas::vector<double, std::vector<double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_BOUNDED_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, bounded" << std::endl;
+    test_my_vector<ublas::bounded_vector<float, 3>, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded" << std::endl;
+    test_my_vector<ublas::bounded_vector<double, 3>, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded" << std::endl;
+    test_my_vector<ublas::bounded_vector<std::complex<float>, 3>, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded" << std::endl;
+    test_my_vector<ublas::bounded_vector<std::complex<double>, 3>, 3> () ();
+#endif
+#endif
+#endif
+}
diff --git a/test/test12.cpp b/test/test12.cpp
new file mode 100644
index 0000000..8c9e61d
--- /dev/null
+++ b/test/test12.cpp
@@ -0,0 +1,277 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test1.hpp"
+
+// Test matrix & vector expression templates
+template<class V, class M, int N>
+struct test_my_matrix_vector {
+    typedef typename V::value_type value_type;
+
+    template<class VP, class MP>
+    void test_with (VP &v1, VP &v2, MP &m1) const {
+        {
+            // Rows and columns
+            initialize_matrix (m1);
+            for (int i = 0; i < N; ++ i) {
+                v1 = ublas::row (m1, i);
+                std::cout << "row (m, " << i << ") = " << v1 << std::endl;
+                v1 = ublas::column (m1, i);
+                std::cout << "column (m, " << i << ") = " << v1 << std::endl;
+            }
+
+            // Outer product
+            initialize_vector (v1);
+            initialize_vector (v2);
+            m1 = ublas::outer_prod (v1, v2);
+            std::cout << "outer_prod (v1, v2) = " << m1 << std::endl;
+
+            // Matrix vector product
+            initialize_matrix (m1);
+            initialize_vector (v1);
+            v2 = ublas::prod (m1, v1);
+            std::cout << "prod (m1, v1) = " << v2 << std::endl;
+            v2 = ublas::prod (v1, m1);
+            std::cout << "prod (v1, m1) = " << v2 << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            V v1 (N), v2 (N);
+            M m1 (N, N);
+            test_with (v1, v2, m1);
+
+            ublas::matrix_row<M> mr1 (m1, 0), mr2 (m1, 1);
+            test_with (mr1, mr2, m1);
+
+            ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 1);
+            test_with (mc1, mc2, m1);
+
+#ifdef USE_RANGE
+            ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                          mvr2 (m1, ublas::range (0, N), ublas::range (0, N));
+            test_with (mvr1, mvr2, m1);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                          mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (mvs1, mvs2, m1);
+#endif
+        }
+    }
+};
+
+// Test matrix & vector
+void test_matrix_vector () {
+    std::cout << "test_matrix_vector" << std::endl;
+
+#ifdef USE_MATRIX
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >,
+                          ublas::matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >,
+                          ublas::matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >,
+                          ublas::matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >,
+                          ublas::matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >,
+                          ublas::matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >,
+                          ublas::matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >,
+                          ublas::matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >,
+                          ublas::matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, std::vector<float> >,
+                          ublas::matrix<float, ublas::row_major, std::vector<float> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, std::vector<double> >,
+                          ublas::matrix<double, ublas::row_major, std::vector<double> >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >,
+                          ublas::matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >,
+                          ublas::matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () ();
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_BOUNDED_MATRIX
+#ifdef USE_FLOAT
+    std::cout << "float, bounded" << std::endl;
+    test_my_matrix_vector<ublas::bounded_vector<float, 3>,
+                          ublas::bounded_matrix<float, 3, 3>, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded" << std::endl;
+    test_my_matrix_vector<ublas::bounded_vector<double, 3>,
+                          ublas::bounded_matrix<double, 3, 3>, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded" << std::endl;
+    test_my_matrix_vector<ublas::bounded_vector<std::complex<float>, 3>,
+                          ublas::bounded_matrix<std::complex<float>, 3, 3>, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded" << std::endl;
+    test_my_matrix_vector<ublas::bounded_vector<std::complex<double>, 3>,
+                          ublas::bounded_matrix<std::complex<double>, 3, 3>, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_VECTOR_OF_VECTOR
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >,
+                          ublas::vector_of_vector<float, ublas::row_major, ublas::bounded_array<ublas::bounded_array<float, 3>, 3 + 1> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >,
+                          ublas::vector_of_vector<double, ublas::row_major, ublas::bounded_array<ublas::bounded_array<double, 3>, 3 + 1> >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >,
+                          ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<float>, 3>, 3 + 1> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >,
+                          ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<double>, 3>, 3 + 1> >, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >,
+                          ublas::vector_of_vector<float, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<float> > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >,
+                          ublas::vector_of_vector<double, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<double> > >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >,
+                          ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<float> > > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >,
+                          ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<double> > > >, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, std::vector<float> >,
+                          ublas::vector_of_vector<float, ublas::row_major, std::vector<std::vector<float> > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, std::vector<double> >,
+                          ublas::vector_of_vector<double, ublas::row_major, std::vector<std::vector<double> > >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >,
+                          ublas::vector_of_vector<std::complex<float>, ublas::row_major, std::vector<std::vector<std::complex<float> > > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >,
+                          ublas::vector_of_vector<std::complex<double>, ublas::row_major, std::vector<std::vector<std::complex<double> > > >, 3> () ();
+#endif
+#endif
+#endif
+#endif
+}
diff --git a/test/test13.cpp b/test/test13.cpp
new file mode 100644
index 0000000..d84f321
--- /dev/null
+++ b/test/test13.cpp
@@ -0,0 +1,325 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test1.hpp"
+
+// Test matrix expression templates
+template<class M, int N>
+struct test_my_matrix {
+    typedef typename M::value_type value_type;
+
+    template<class VP>
+    void test_container_with (VP &v1) const {
+        // Container type tests in addition to expression types
+        // Insert and erase
+        v1.insert_element (0,0, 55);
+        v1.erase_element (1,1);
+        v1.clear ();
+    }
+    
+    template<class MP>
+    void test_expression_with (MP &m1, MP &m2, MP &m3) const {
+        value_type t;
+
+        // Default Construct
+        default_construct<MP>::test ();
+        
+        // Copy and swap
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        m1 = m2;
+        std::cout << "m1 = m2 = " << m1 << std::endl;
+        m1.assign_temporary (m2);
+        std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl;
+        m1.swap (m2);
+        std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl;
+
+        // Zero assignment
+        m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ());
+        std::cout << "m1.zero_matrix = " << m1 << std::endl;
+        m1 = m2;
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+            // Project range and slice
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::range(0,1),ublas::range(0,1));
+        project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::slice(0,1,1),ublas::slice(0,1,1));
+        project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::slice(0,1,2),ublas::slice(0,1,2));
+        project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::range(0,2),ublas::range(0,2));
+        std::cout << "m1 = range/slice " << m1 << std::endl;
+#endif
+
+            // Unary matrix operations resulting in a matrix
+        initialize_matrix (m1);
+        m2 = - m1;
+        std::cout << "- m1 = " << m2 << std::endl;
+        m2 = ublas::conj (m1);
+        std::cout << "conj (m1) = " << m2 << std::endl;
+
+        // Binary matrix operations resulting in a matrix
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        m3 = m1 + m2;
+        std::cout << "m1 + m2 = " << m3 << std::endl;
+        m3 = m1 - m2;
+        std::cout << "m1 - m2 = " << m3 << std::endl;
+        m3 = ublas::element_prod (m1, m2);
+        std::cout << "element_prod (m1, m2) = " << m3 << std::endl;
+
+        // Scaling a matrix
+        t = N;
+        initialize_matrix (m1);
+        m2 = value_type (1.) * m1;
+        std::cout << "1. * m1 = " << m2 << std::endl;
+        m2 = t * m1;
+        std::cout << "N * m1 = " << m2 << std::endl;
+        initialize_matrix (m1);
+        m2 = m1 * value_type (1.);
+        std::cout << "m1 * 1. = " << m2 << std::endl;
+        m2 = m1 * t;
+        std::cout << "m1 * N = " << m2 << std::endl;
+        m2 = m1 / value_type (2.);
+        std::cout << "m1 / 2. = " << m2 << std::endl;
+        m2 = m1 / t;
+        std::cout << "m1 / N = " << m2 << std::endl;
+
+        // Some assignments
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        m2 += m1;
+        std::cout << "m2 += m1 = " << m2 << std::endl;
+        m2 -= m1;
+        std::cout << "m2 -= m1 = " << m2 << std::endl;
+        m2 = m2 + m1;
+        std::cout << "m2 = m2 + m1 = " << m2 << std::endl;
+        m2 = m2 - m1;
+        std::cout << "m2 = m2 - m1 = " << m2 << std::endl;
+        m1 *= value_type (1.);
+        std::cout << "m1 *= 1. = " << m1 << std::endl;
+        m1 *= t;
+        std::cout << "m1 *= N = " << m1 << std::endl;
+
+        // Transpose
+        initialize_matrix (m1);
+        m2 = ublas::trans (m1);
+        std::cout << "trans (m1) = " << m2 << std::endl;
+
+        // Hermitean
+        initialize_matrix (m1);
+        m2 = ublas::herm (m1);
+        std::cout << "herm (m1) = " << m2 << std::endl;
+
+        // Matrix multiplication
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        m3 = ublas::prod (m1, m2);
+        std::cout << "prod (m1, m2) = " << m3 << std::endl;
+    }
+
+    void operator () () const {
+        M m1 (N, N), m2 (N, N), m3 (N, N);
+        test_expression_with (m1, m2, m3);
+        test_container_with (m1);
+
+#ifdef USE_RANGE
+        ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                               mr2 (m2, ublas::range (0, N), ublas::range (0, N)),
+                               mr3 (m3, ublas::range (0, N), ublas::range (0, N));
+        test_expression_with (mr1, mr2, mr3);
+#endif
+
+#ifdef USE_SLICE
+        ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                               ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                               ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+        test_expression_with (ms1, ms2, ms3);
+#endif
+    }
+};
+
+// Test matrix
+void test_matrix () {
+    std::cout << "test_matrix" << std::endl;
+
+#ifdef USE_MATRIX
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix<ublas::matrix<float, ublas::row_major, std::vector<float> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix<ublas::matrix<double, ublas::row_major, std::vector<double> >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix<ublas::matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix<ublas::matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () ();
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_BOUNDED_MATRIX
+#ifdef USE_FLOAT
+    std::cout << "float, bounded" << std::endl;
+    test_my_matrix<ublas::bounded_matrix<float, 3, 3>, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded" << std::endl;
+    test_my_matrix<ublas::bounded_matrix<double, 3, 3>, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded" << std::endl;
+    test_my_matrix<ublas::bounded_matrix<std::complex<float>, 3, 3>, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded" << std::endl;
+    test_my_matrix<ublas::bounded_matrix<std::complex<double>, 3, 3>, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_VECTOR_OF_VECTOR
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<float, ublas::row_major, ublas::bounded_array<ublas::bounded_array<float, 3>, 3 + 1> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<double, ublas::row_major, ublas::bounded_array<ublas::bounded_array<double, 3>, 3 + 1> >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<float>, 3>, 3 + 1> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<std::complex<double>, 3>, 3 + 1> >, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<float, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<float> > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<double, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<double> > >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<std::complex<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<float> > > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<std::complex<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<std::complex<double> > > >, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<float, ublas::row_major, std::vector<std::vector<float > > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<double, ublas::row_major, std::vector<std::vector<double> > >, 3> () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<std::complex<float>, ublas::row_major, std::vector<std::vector<std::complex<float> > > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<std::complex<double>, ublas::row_major, std::vector<std::vector<std::complex<double> > > >, 3> () ();
+#endif
+#endif
+#endif
+#endif
+}
diff --git a/test/test2.cpp b/test/test2.cpp
new file mode 100644
index 0000000..07a4c75
--- /dev/null
+++ b/test/test2.cpp
@@ -0,0 +1,87 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test2.hpp"
+
+int main () {
+#ifdef USE_FLOAT
+    std::cout << "float" << std::endl;
+    test_blas_1<ublas::vector<float>, 3> ().test ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double" << std::endl;
+    test_blas_1<ublas::vector<double>, 3> ().test ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>" << std::endl;
+    test_blas_1<ublas::vector<std::complex<float> >, 3> ().test ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>" << std::endl;
+    test_blas_1<ublas::vector<std::complex<double> >, 3> ().test ();
+#endif
+#endif
+
+    std::cout << "test_blas_2" << std::endl;
+
+#ifdef USE_FLOAT
+    std::cout << "float" << std::endl;
+    test_blas_2<ublas::vector<float>, ublas::matrix<float>, 3> ().test ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double" << std::endl;
+    test_blas_2<ublas::vector<double>, ublas::matrix<double>, 3> ().test ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>" << std::endl;
+    test_blas_2<ublas::vector<std::complex<float> >, ublas::matrix<std::complex<float> >, 3> ().test ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>" << std::endl;
+    test_blas_2<ublas::vector<std::complex<double> >, ublas::matrix<std::complex<double> >, 3> ().test ();
+#endif
+#endif
+
+    std::cout << "test_blas_3" << std::endl;
+
+#ifdef USE_FLOAT
+    std::cout << "float" << std::endl;
+    test_blas_3<ublas::matrix<float>, 3> ().test ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double" << std::endl;
+    test_blas_3<ublas::matrix<double>, 3> ().test ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>" << std::endl;
+    test_blas_3<ublas::matrix<std::complex<float> >, 3> ().test ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>" << std::endl;
+    test_blas_3<ublas::matrix<std::complex<double> >, 3> ().test ();
+#endif
+#endif
+
+    return 0;
+}
diff --git a/test/test2.hpp b/test/test2.hpp
new file mode 100644
index 0000000..d4d4baa
--- /dev/null
+++ b/test/test2.hpp
@@ -0,0 +1,51 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef TEST2_H
+#define TEST2_H
+
+#include <iostream>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/numeric/ublas/blas.hpp>
+
+namespace ublas = boost::numeric::ublas;
+
+#include "common/init.hpp"
+
+template<class V, std::size_t N>
+struct test_blas_1 {
+    typedef typename V::value_type value_type;
+    typedef typename ublas::type_traits<value_type>::real_type real_type;
+
+    void test ();
+};
+
+template<class V, class M, std::size_t N>
+struct test_blas_2 {
+    typedef typename V::value_type value_type;
+
+    void test ();
+};
+
+template<class M, std::size_t N>
+struct test_blas_3 {
+    typedef typename M::value_type value_type;
+
+    void test ();
+};
+
+
+#endif
diff --git a/test/test21.cpp b/test/test21.cpp
new file mode 100644
index 0000000..408b17d
--- /dev/null
+++ b/test/test21.cpp
@@ -0,0 +1,95 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test2.hpp"
+
+template<class V, std::size_t N>
+void test_blas_1<V, N>::test () {
+    {
+        value_type t;
+        real_type n;
+        V v1 (N), v2 (N);
+
+        // _asum
+        initialize_vector (v1);
+        n = ublas::blas_1::asum (v1);
+        std::cout << "asum (v1) = " << n << std::endl;
+
+        // _amax
+        initialize_vector (v1);
+        n = ublas::blas_1::amax (v1);
+        std::cout << "amax (v1) = " << n << std::endl;
+
+        // _nrm2
+        initialize_vector (v1);
+        n = ublas::blas_1::nrm2 (v1);
+        std::cout << "nrm2 (v1) = " << n << std::endl;
+
+        // _dot
+        // _dotu
+        // _dotc
+        initialize_vector (v1);
+        initialize_vector (v2);
+        t = ublas::blas_1::dot (v1, v2);
+        std::cout << "dot (v1, v2) = " << t << std::endl;
+        t = ublas::blas_1::dot (ublas::conj (v1), v2);
+        std::cout << "dot (conj (v1), v2) = " << t << std::endl;
+
+        // _copy
+        initialize_vector (v2);
+        ublas::blas_1::copy (v1, v2);
+        std::cout << "copy (v1, v2) = " << v1 << std::endl;
+
+        // _swap
+        initialize_vector (v1);
+        initialize_vector (v2);
+        ublas::blas_1::swap (v1, v2);
+        std::cout << "swap (v1, v2) = " << v1 << " " << v2 << std::endl;
+
+        // _scal
+        // csscal
+        // zdscal
+        initialize_vector (v1);
+        ublas::blas_1::scal (v1, value_type (1));
+        std::cout << "scal (v1, 1) = " << v1 << std::endl;
+
+        // _axpy
+        initialize_vector (v1);
+        initialize_vector (v2);
+        ublas::blas_1::axpy (v1, value_type (1), v2);
+        std::cout << "axpy (v1, 1, v2) = " << v1 << std::endl;
+
+        // _rot
+        initialize_vector (v1);
+        initialize_vector (v2);
+        ublas::blas_1::rot (value_type (1), v1, value_type (1), v2);
+        std::cout << "rot (1, v1, 1, v2) = " << v1 << " " << v2 << std::endl;
+    }
+}
+
+#ifdef USE_FLOAT
+template struct test_blas_1<ublas::vector<float>, 3>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct test_blas_1<ublas::vector<double>, 3>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct test_blas_1<ublas::vector<std::complex<float> >, 3>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct test_blas_1<ublas::vector<std::complex<double> >, 3>;
+#endif
+#endif
diff --git a/test/test22.cpp b/test/test22.cpp
new file mode 100644
index 0000000..13b313e
--- /dev/null
+++ b/test/test22.cpp
@@ -0,0 +1,147 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test2.hpp"
+
+template<class V, class M, std::size_t N>
+void test_blas_2<V, M, N>::test () {
+    {
+        V v1 (N), v2 (N);
+        M m (N, N);
+
+        // _t_mv
+        initialize_vector (v1);
+        initialize_matrix (m);
+        ublas::blas_2::tmv (v1, m);
+        std::cout << "tmv (v1, m) = " << v1 << std::endl;
+        initialize_vector (v1);
+        initialize_matrix (m);
+        ublas::blas_2::tmv (v1, ublas::trans (m));
+        std::cout << "tmv (v1, trans (m)) = " << v1 << std::endl;
+#ifdef USE_STD_COMPLEX
+        initialize_vector (v1);
+        initialize_matrix (m);
+        ublas::blas_2::tmv (v1, ublas::herm (m));
+        std::cout << "tmv (v1, herm (m)) = " << v1 << std::endl;
+#endif
+
+        // _t_sv
+        initialize_vector (v1);
+        initialize_vector (v2);
+        initialize_matrix (m, ublas::lower_tag ());
+        ublas::blas_2::tsv (v1, m, ublas::lower_tag ());
+        std::cout << "tsv (v1, m) = " << v1 << " " << ublas::prod (m, v1) - v2 << std::endl;
+        initialize_vector (v1);
+        initialize_vector (v2);
+        initialize_matrix (m, ublas::upper_tag ());
+        ublas::blas_2::tsv (v1, ublas::trans (m), ublas::lower_tag ());
+        std::cout << "tsv (v1, trans (m)) = " << v1 << " " << ublas::prod (ublas::trans (m), v1) - v2 << std::endl;
+#ifdef USE_STD_COMPLEX
+        initialize_vector (v1);
+        initialize_vector (v2);
+        initialize_matrix (m, ublas::upper_tag ());
+        ublas::blas_2::tsv (v1, ublas::herm (m), ublas::lower_tag ());
+        std::cout << "tsv (v1, herm (m)) = " << v1 << " " << ublas::prod (ublas::herm (m), v1) - v2 << std::endl;
+#endif
+        initialize_vector (v1);
+        initialize_vector (v2);
+        initialize_matrix (m, ublas::upper_tag ());
+        ublas::blas_2::tsv (v1, m, ublas::upper_tag ());
+        std::cout << "tsv (v1, m) = " << v1 << " " << ublas::prod (m, v1) - v2 << std::endl;
+        initialize_vector (v1);
+        initialize_vector (v2);
+        initialize_matrix (m, ublas::lower_tag ());
+        ublas::blas_2::tsv (v1, ublas::trans (m), ublas::upper_tag ());
+        std::cout << "tsv (v1, trans (m)) = " << v1 << " " << ublas::prod (ublas::trans (m), v1) - v2 << std::endl;
+#ifdef USE_STD_COMPLEX
+        initialize_vector (v1);
+        initialize_vector (v2);
+        initialize_matrix (m, ublas::lower_tag ());
+        ublas::blas_2::tsv (v1, ublas::herm (m), ublas::upper_tag ());
+        std::cout << "tsv (v1, herm (m)) = " << v1 << " " << ublas::prod (ublas::herm (m), v1) - v2 << std::endl;
+#endif
+
+        // _g_mv
+        // _s_mv
+        // _h_mv
+        initialize_vector (v1);
+        initialize_vector (v2);
+        initialize_matrix (m);
+        ublas::blas_2::gmv (v1, value_type (1), value_type (1), m, v2);
+        std::cout << "gmv (v1, 1, 1, m, v2) = " << v1 << std::endl;
+        ublas::blas_2::gmv (v1, value_type (1), value_type (1), ublas::trans (m), v2);
+        std::cout << "gmv (v1, 1, 1, trans (m), v2) = " << v1 << std::endl;
+#ifdef USE_STD_COMPLEX
+        ublas::blas_2::gmv (v1, value_type (1), value_type (1), ublas::herm (m), v2);
+        std::cout << "gmv (v1, 1, 1, herm (m), v2) = " << v1 << std::endl;
+#endif
+
+        // _g_r
+        // _g_ru
+        // _g_rc
+        initialize_vector (v1);
+        initialize_vector (v2);
+        initialize_matrix (m);
+        ublas::blas_2::gr (m, value_type (1), v1, v2);
+        std::cout << "gr (m, 1, v1, v2) = " << m << std::endl;
+        ublas::blas_2::gr (m, value_type (1), v1, ublas::conj (v2));
+        std::cout << "gr (m, 1, v1, conj (v2)) = " << m << std::endl;
+
+        // _s_r
+        initialize_vector (v1);
+        initialize_matrix (m);
+        ublas::blas_2::sr (m, value_type (1), v1);
+        std::cout << "sr (m, 1, v1) = " << m << std::endl;
+
+#ifdef USE_STD_COMPLEX
+        // _h_r
+        initialize_vector (v1);
+        initialize_matrix (m);
+        ublas::blas_2::hr (m, value_type (1), v1);
+        std::cout << "hr (m, 1, v1) = " << m << std::endl;
+#endif
+
+        // _s_r2
+        initialize_vector (v1);
+        initialize_vector (v2);
+        initialize_matrix (m);
+        ublas::blas_2::sr2 (m, value_type (1), v1, v2);
+        std::cout << "sr2 (m, 1, v1, v2) = " << m << std::endl;
+
+#ifdef USE_STD_COMPLEX
+        // _h_r2
+        initialize_vector (v1);
+        initialize_vector (v2);
+        initialize_matrix (m);
+        ublas::blas_2::hr2 (m, value_type (1), v1, v2);
+        std::cout << "hr2 (m, 1, v1, v2) = " << m << std::endl;
+#endif
+    }
+}
+
+#ifdef USE_FLOAT
+template struct test_blas_2<ublas::vector<float>, ublas::matrix<float>, 3>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct test_blas_2<ublas::vector<double>, ublas::matrix<double>, 3>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct test_blas_2<ublas::vector<std::complex<float> >, ublas::matrix<std::complex<float> >, 3>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct test_blas_2<ublas::vector<std::complex<double> >, ublas::matrix<std::complex<double> >, 3>;
+#endif
+#endif
diff --git a/test/test23.cpp b/test/test23.cpp
new file mode 100644
index 0000000..2817710
--- /dev/null
+++ b/test/test23.cpp
@@ -0,0 +1,208 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test2.hpp"
+
+template<class M, std::size_t N>
+void test_blas_3<M, N>::test () {
+    {
+        M m1 (N, N), m2 (N, N), m3 (N, N);
+
+        // _t_mm
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::tmm (m1, value_type (1), m2, m1);
+        std::cout << "tmm (m1, 1, m2, m1) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::tmm (m1, value_type (1), m2, ublas::trans (m1));
+        std::cout << "tmm (m1, 1, m2, trans (m1)) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::tmm (m1, value_type (1), ublas::trans (m2), m1);
+        std::cout << "tmm (m1, 1, trans (m2), m1) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::tmm (m1, value_type (1), ublas::trans (m2), ublas::trans (m1));
+        std::cout << "tmm (m1, 1, trans (m2), trans (m1)) = " << m1 << std::endl;
+#ifdef USE_STD_COMPLEX
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::tmm (m1, value_type (1), m2, ublas::herm (m1));
+        std::cout << "tmm (m1, 1, m2, herm (m1)) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::tmm (m1, value_type (1), ublas::herm (m2), m1);
+        std::cout << "tmm (m1, 1, herm (m2), m1) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::tmm (m1, value_type (1), ublas::trans (m2), ublas::herm (m1));
+        std::cout << "tmm (m1, 1, trans (m2), herm (m1)) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::tmm (m1, value_type (1), ublas::herm (m2), ublas::trans (m1));
+        std::cout << "tmm (m1, 1, herm (m2), trans (m1)) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::tmm (m1, value_type (1), ublas::herm (m2), ublas::herm (m1));
+        std::cout << "tmm (m1, 1, herm (m2), herm (m1)) = " << m1 << std::endl;
+#endif
+
+        // _t_sm
+        initialize_matrix (m1);
+        initialize_matrix (m2, ublas::lower_tag ());
+        initialize_matrix (m3);
+        ublas::blas_3::tsm (m1, value_type (1), m2, ublas::lower_tag ());
+        std::cout << "tsm (m1, 1, m2) = " << m1 << " " << ublas::prod (m2, m1) - value_type (1) * m3 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2, ublas::upper_tag ());
+        ublas::blas_3::tsm (m1, value_type (1), ublas::trans (m2), ublas::lower_tag ());
+        std::cout << "tsm (m1, 1, trans (m2)) = " << m1 << " " << ublas::prod (ublas::trans (m2), m1) - value_type (1) * m3 << std::endl;
+#ifdef USE_STD_COMPLEX
+        initialize_matrix (m1);
+        initialize_matrix (m2, ublas::upper_tag ());
+        ublas::blas_3::tsm (m1, value_type (1), ublas::herm (m2), ublas::lower_tag ());
+        std::cout << "tsm (m1, 1, herm (m2)) = " << m1 << " " << ublas::prod (ublas::herm (m2), m1) - value_type (1) * m3 << std::endl;
+#endif
+        initialize_matrix (m1);
+        initialize_matrix (m2, ublas::upper_tag ());
+        ublas::blas_3::tsm (m1, value_type (1), m2, ublas::upper_tag ());
+        std::cout << "tsm (m1, 1, m2) = " << m1 << " " << ublas::prod (m2, m1) - value_type (1) * m3 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2, ublas::lower_tag ());
+        ublas::blas_3::tsm (m1, value_type (1), ublas::trans (m2), ublas::upper_tag ());
+        std::cout << "tsm (m1, 1, trans (m2)) = " << m1 << " " << ublas::prod (ublas::trans (m2), m1) - value_type (1) * m3 << std::endl;
+#ifdef USE_STD_COMPLEX
+        initialize_matrix (m1);
+        initialize_matrix (m2, ublas::lower_tag ());
+        ublas::blas_3::tsm (m1, value_type (1), ublas::herm (m2), ublas::upper_tag ());
+        std::cout << "tsm (m1, 1, herm (m2)) = " << m1 << " " << ublas::prod (ublas::herm (m2), m1) - value_type (1) * m3 << std::endl;
+#endif
+
+        // _g_mm
+        // _s_mm
+        // _h_mm
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::gmm (m1, value_type (1), value_type (1), m2, m3);
+        std::cout << "gmm (m1, 1, 1, m2, m3) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::trans (m2), m3);
+        std::cout << "gmm (m1, 1, 1, trans (m2), m3) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::gmm (m1, value_type (1), value_type (1), m2, ublas::trans (m3));
+        std::cout << "gmm (m1, 1, 1, m2, trans (m3)) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::trans (m2), ublas::trans (m3));
+        std::cout << "gmm (m1, 1, 1, trans (m2), trans (m3)) = " << m1 << std::endl;
+#ifdef USE_STD_COMPLEX
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::herm (m2), m3);
+        std::cout << "gmm (m1, 1, 1, herm (m2), m3) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::gmm (m1, value_type (1), value_type (1), m2, ublas::herm (m3));
+        std::cout << "gmm (m1, 1, 1, m2, herm (m3)) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::herm (m2), ublas::trans (m3));
+        std::cout << "gmm (m1, 1, 1, herm (m2), trans (m3)) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::trans (m2), ublas::herm (m3));
+        std::cout << "gmm (m1, 1, 1, trans (m2), herm (m3)) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::gmm (m1, value_type (1), value_type (1), ublas::herm (m2), ublas::herm (m3));
+        std::cout << "gmm (m1, 1, 1, herm (m2), herm (m3)) = " << m1 << std::endl;
+#endif
+
+        // s_rk
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::srk (m1, value_type (1), value_type (1), m2);
+        std::cout << "srk (m1, 1, 1, m2) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::srk (m1, value_type (1), value_type (1), ublas::trans (m2));
+        std::cout << "srk (m1, 1, 1, trans (m2)) = " << m1 << std::endl;
+
+#ifdef USE_STD_COMPLEX
+        // h_rk
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::hrk (m1, value_type (1), value_type (1), m2);
+        std::cout << "hrk (m1, 1, 1, m2) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        ublas::blas_3::hrk (m1, value_type (1), value_type (1), ublas::herm (m2));
+        std::cout << "hrk (m1, 1, 1, herm (m2)) = " << m1 << std::endl;
+#endif
+
+        // s_r2k
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::sr2k (m1, value_type (1), value_type (1), m2, m3);
+        std::cout << "sr2k (m1, 1, 1, m2, m3) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::sr2k (m1, value_type (1), value_type (1), ublas::trans (m2), ublas::trans (m3));
+        std::cout << "sr2k (m1, 1, 1, trans (m2), trans (m3)) = " << m1 << std::endl;
+
+#ifdef USE_STD_COMPLEX
+        // h_r2k
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::hr2k (m1, value_type (1), value_type (1), m2, m3);
+        std::cout << "hr2k (m1, 1, 1, m2, m3) = " << m1 << std::endl;
+        initialize_matrix (m1);
+        initialize_matrix (m2);
+        initialize_matrix (m3);
+        ublas::blas_3::hr2k (m1, value_type (1), value_type (1), ublas::herm (m2), ublas::herm (m3));
+        std::cout << "hr2k (m1, 1, 1, herm (m2), herm (m3)) = " << m1 << std::endl;
+#endif
+    }
+}
+
+#ifdef USE_FLOAT
+template struct test_blas_3<ublas::matrix<float>, 3>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct test_blas_3<ublas::matrix<double>, 3>;
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+template struct test_blas_3<ublas::matrix<std::complex<float> >, 3>;
+#endif
+
+#ifdef USE_DOUBLE
+template struct test_blas_3<ublas::matrix<std::complex<double> >, 3>;
+#endif
+#endif
diff --git a/test/test3.cpp b/test/test3.cpp
new file mode 100644
index 0000000..fb2b94d
--- /dev/null
+++ b/test/test3.cpp
@@ -0,0 +1,20 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test3.hpp"
+
+int main () {
+    test_vector ();
+    test_matrix_vector ();
+    test_matrix ();
+    return 0;
+}
diff --git a/test/test3.hpp b/test/test3.hpp
new file mode 100644
index 0000000..a9d4fc9
--- /dev/null
+++ b/test/test3.hpp
@@ -0,0 +1,38 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef TEST3_H
+#define TEST3_H
+
+#include <iostream>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#ifdef USE_GENERALIZED_VECTOR_OF_VECTOR
+#include <boost/numeric/ublas/vector_of_vector.hpp>
+#endif
+#include <boost/numeric/ublas/io.hpp>
+
+namespace ublas = boost::numeric::ublas;
+
+#include "common/init.hpp"
+
+void test_vector ();
+void test_matrix_vector ();
+void test_matrix ();
+
+#endif
diff --git a/test/test31.cpp b/test/test31.cpp
new file mode 100644
index 0000000..7762287
--- /dev/null
+++ b/test/test31.cpp
@@ -0,0 +1,248 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test3.hpp"
+
+// Test vector expression templates
+template<class V, int N>
+struct test_my_vector {
+    typedef typename V::value_type value_type;
+    typedef typename V::size_type size_type;
+    typedef typename ublas::type_traits<value_type>::real_type real_type;
+
+    template<class VP>
+    void test_with (VP &v1, VP &v2, VP &v3) const {
+        {
+            value_type t;
+            size_type i;
+            real_type n;
+
+            // Default Construct
+            default_construct<VP>::test ();
+            
+            // Copy and swap
+            initialize_vector (v1);
+            initialize_vector (v2);
+            v1 = v2;
+            std::cout << "v1 = v2 = " << v1 << std::endl;
+            v1.assign_temporary (v2);
+            std::cout << "v1.assign_temporary (v2) = " << v1 << std::endl;
+            v1.swap (v2);
+            std::cout << "v1.swap (v2) = " << v1 << " " << v2 << std::endl;
+
+            // Zero assignment
+            v1 = ublas::zero_vector<> (v1.size ());
+            std::cout << "v1.zero_vector = " << v1 << std::endl;
+            v1 = v2;
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+            // Project range and slice
+            initialize_vector (v1);
+            initialize_vector (v2);
+            project (v1, ublas::range(0,1)) = project (v2, ublas::range(0,1));
+            project (v1, ublas::range(0,1)) = project (v2, ublas::slice(0,1,1));
+            project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::slice(0,1,2));
+            project (v1, ublas::slice(2,-1,2)) = project (v2, ublas::range(0,2));
+            std::cout << "v1 = range/slice " << v1 << std::endl;
+#endif
+
+            // Unary vector operations resulting in a vector
+            initialize_vector (v1);
+            v2 = - v1;
+            std::cout << "- v1 = " << v2 << std::endl;
+            v2 = ublas::conj (v1);
+            std::cout << "conj (v1) = " << v2 << std::endl;
+
+            // Binary vector operations resulting in a vector
+            initialize_vector (v1);
+            initialize_vector (v2);
+            initialize_vector (v3);
+            v3 = v1 + v2;
+            std::cout << "v1 + v2 = " << v3 << std::endl;
+
+            v3 = v1 - v2;
+            std::cout << "v1 - v2 = " << v3 << std::endl;
+
+            // Scaling a vector
+            t = N;
+            initialize_vector (v1);
+            v2 = value_type (1.) * v1;
+            std::cout << "1. * v1 = " << v2 << std::endl;
+            v2 = t * v1;
+            std::cout << "N * v1 = " << v2 << std::endl;
+            initialize_vector (v1);
+            v2 = v1 * value_type (1.);
+            std::cout << "v1 * 1. = " << v2 << std::endl;
+            v2 = v1 * t;
+            std::cout << "v1 * N = " << v2 << std::endl;
+
+            // Some assignments
+            initialize_vector (v1);
+            initialize_vector (v2);
+            v2 += v1;
+            std::cout << "v2 += v1 = " << v2 << std::endl;
+            v2 -= v1;
+            std::cout << "v2 -= v1 = " << v2 << std::endl;
+            v2 = v2 + v1;
+            std::cout << "v2 = v2 + v1 = " << v2 << std::endl;
+            v2 = v2 - v1;
+            std::cout << "v2 = v2 - v1 = " << v2 << std::endl;
+            v1 *= value_type (1.);
+            std::cout << "v1 *= 1. = " << v1 << std::endl;
+            v1 *= t;
+            std::cout << "v1 *= N = " << v1 << std::endl;
+
+            // Unary vector operations resulting in a scalar
+            initialize_vector (v1);
+            t = ublas::sum (v1);
+            std::cout << "sum (v1) = " << t << std::endl;
+            n = ublas::norm_1 (v1);
+            std::cout << "norm_1 (v1) = " << n << std::endl;
+            n = ublas::norm_2 (v1);
+            std::cout << "norm_2 (v1) = " << n << std::endl;
+            n = ublas::norm_inf (v1);
+            std::cout << "norm_inf (v1) = " << n << std::endl;
+
+            i = ublas::index_norm_inf (v1);
+            std::cout << "index_norm_inf (v1) = " << i << std::endl;
+
+            // Binary vector operations resulting in a scalar
+            initialize_vector (v1);
+            initialize_vector (v2);
+            t = ublas::inner_prod (v1, v2);
+            std::cout << "inner_prod (v1, v2) = " << t << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            V v1 (N, N), v2 (N, N), v3 (N, N);
+            test_with (v1, v2, v3);
+
+#ifdef USE_RANGE
+            ublas::vector_range<V> vr1 (v1, ublas::range (0, N)),
+                                   vr2 (v2, ublas::range (0, N)),
+                                   vr3 (v3, ublas::range (0, N));
+            test_with (vr1, vr2, vr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::vector_slice<V> vs1 (v1, ublas::slice (0, 1, N)),
+                                   vs2 (v2, ublas::slice (0, 1, N)),
+                                   vs3 (v3, ublas::slice (0, 1, N));
+            test_with (vs1, vs2, vs3);
+#endif
+        }
+    }
+};
+
+// Test vector
+void test_vector () {
+    std::cout << "test_vector" << std::endl;
+
+#ifdef USE_SPARSE_VECTOR
+#ifdef USE_MAP_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, map_array" << std::endl;
+    test_my_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, map_array" << std::endl;
+    test_my_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, map_array" << std::endl;
+    test_my_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, map_array" << std::endl;
+    test_my_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_MAP
+#ifdef USE_FLOAT
+    std::cout << "float, std::map" << std::endl;
+    test_my_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::map" << std::endl;
+    test_my_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::map" << std::endl;
+    test_my_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::map" << std::endl;
+    test_my_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > , 3 > () ();
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_COMPRESSED_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float compressed" << std::endl;
+    test_my_vector<ublas::compressed_vector<float>, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double compressed" << std::endl;
+    test_my_vector<ublas::compressed_vector<double>, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float> compressed" << std::endl;
+    test_my_vector<ublas::compressed_vector<std::complex<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double> compressed" << std::endl;
+    test_my_vector<ublas::compressed_vector<std::complex<double> >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_COORDINATE_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float coordinate" << std::endl;
+    test_my_vector<ublas::coordinate_vector<float>, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double coordinate" << std::endl;
+    test_my_vector<ublas::coordinate_vector<double>, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float> coordinate" << std::endl;
+    test_my_vector<ublas::coordinate_vector<std::complex<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double> coordinate" << std::endl;
+    test_my_vector<ublas::coordinate_vector<std::complex<double> >, 3 > () ();
+#endif
+#endif
+#endif
+}
diff --git a/test/test32.cpp b/test/test32.cpp
new file mode 100644
index 0000000..eaf4929
--- /dev/null
+++ b/test/test32.cpp
@@ -0,0 +1,354 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test3.hpp"
+
+// Test matrix & vector expression templates
+template<class V, class M, int N>
+struct test_my_matrix_vector {
+    typedef typename V::value_type value_type;
+
+    template<class VP, class MP>
+    void test_with (VP &v1, VP &v2, MP &m1) const {
+        {
+            // Rows and columns
+            initialize_matrix (m1);
+            for (int i = 0; i < N; ++ i) {
+                v1 = ublas::row (m1, i);
+                std::cout << "row (m, " << i << ") = " << v1 << std::endl;
+                v1 = ublas::column (m1, i);
+                std::cout << "column (m, " << i << ") = " << v1 << std::endl;
+            }
+
+            // Outer product
+            initialize_vector (v1);
+            initialize_vector (v2);
+            m1 = ublas::outer_prod (v1, v2);
+            std::cout << "outer_prod (v1, v2) = " << m1 << std::endl;
+
+            // Matrix vector product
+            initialize_matrix (m1);
+            initialize_vector (v1);
+            v2 = ublas::prod (m1, v1);
+            std::cout << "prod (m1, v1) = " << v2 << std::endl;
+            v2 = ublas::prod (v1, m1);
+            std::cout << "prod (v1, m1) = " << v2 << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            V v1 (N, N), v2 (N, N);
+            M m1 (N, N, N * N);
+
+            test_with (v1, v2, m1);
+
+            ublas::matrix_row<M> mr1 (m1, 0), mr2 (m1, N - 1);
+            test_with (mr1, mr2, m1);
+
+            ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, N - 1);
+            test_with (mc1, mc2, m1);
+
+#ifdef USE_RANGE
+            ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                          mvr2 (m1, ublas::range (0, N), ublas::range (0, N));
+            test_with (mvr1, mvr2, m1);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                          mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (mvs1, mvs2, m1);
+#endif
+        }
+    }
+};
+
+// Test matrix & vector
+void test_matrix_vector () {
+    std::cout << "test_matrix_vector" << std::endl;
+
+#ifdef USE_SPARSE_MATRIX
+#ifdef USE_MAP_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >,
+                          ublas::mapped_matrix<float, ublas::row_major, ublas::map_array<std::size_t, float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >,
+                          ublas::mapped_matrix<double, ublas::row_major, ublas::map_array<std::size_t, double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >,
+                          ublas::mapped_matrix<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >,
+                          ublas::mapped_matrix<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_MAP
+#ifdef USE_FLOAT
+    std::cout << "float, std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >,
+                          ublas::mapped_matrix<float, ublas::row_major, std::map<std::size_t, float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >,
+                          ublas::mapped_matrix<double, ublas::row_major, std::map<std::size_t, double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >,
+                          ublas::mapped_matrix<std::complex<float>, ublas::row_major, std::map<std::size_t, std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >,
+                          ublas::mapped_matrix<std::complex<double>, ublas::row_major, std::map<std::size_t, std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_SPARSE_VECTOR_OF_SPARSE_VECTOR
+#ifdef USE_MAP_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, mapped_vector map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >,
+                          ublas::mapped_vector<float, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, mapped_vector map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >,
+                          ublas::mapped_vector<double, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, double> > >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, mapped_vector map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >,
+                          ublas::mapped_vector<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<float> > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>,mapped_vector map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >,
+                          ublas::mapped_vector<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<double> > > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_MAP
+#ifdef USE_FLOAT
+    std::cout << "float, mapped_vector std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >,
+                          ublas::mapped_vector<float, ublas::row_major, std::map<std::size_t, std::map<std::size_t, float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, mapped_vector std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >,
+                          ublas::mapped_vector<double, ublas::row_major, std::map<std::size_t, std::map<std::size_t, double> > >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, mapped_vector std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >,
+                          ublas::mapped_vector<std::complex<float>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<float> > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, mapped_vector std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >,
+                          ublas::mapped_vector<std::complex<double>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<double> > > >, 3 > () ();
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_GENERALIZED_VECTOR_OF_VECTOR
+#ifdef USE_MAP_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, generalized_vector_of_vector map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >,
+                          ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > >, 3 > () ();
+    test_my_matrix_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >,
+                          ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, ublas::map_array<std::size_t, ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, generalized_vector_of_vector map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >,
+                          ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > >, 3 > () ();
+    test_my_matrix_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >,
+                          ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, ublas::map_array<std::size_t, ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > > >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, generalized_vector_of_vector map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >,
+                          ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > >, 3 > () ();
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >,
+                          ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, generalized_vector_of_vector map_array" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >,
+                          ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > >, 3 > () ();
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >,
+                          ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_MAP
+#ifdef USE_FLOAT
+    std::cout << "float, generalized_vector_of_vector std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >,
+                          ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, std::map<std::size_t, float> > > >, 3 > () ();
+    test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >,
+                          ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, std::map<std::size_t, ublas::mapped_vector<float, std::map<std::size_t, float> > > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, generalized_vector_of_vector std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >,
+                          ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, std::map<std::size_t, double> > > >, 3 > () ();
+    test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >,
+                          ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, std::map<std::size_t, ublas::mapped_vector<double, std::map<std::size_t, double> > > > >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, generalized_vector_of_vector std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >,
+                          ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > >, 3 > () ();
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >,
+                          ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, generalized_vector_of_vector std::map" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >,
+                          ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > >, 3 > () ();
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >,
+                          ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > > >, 3 > () ();
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_COMPRESSED_MATRIX
+#ifdef USE_FLOAT
+    std::cout << "float compressed" << std::endl;
+    test_my_matrix_vector<ublas::compressed_vector<float>,
+                          ublas::compressed_matrix<float>, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double compressed" << std::endl;
+    test_my_matrix_vector<ublas::compressed_vector<double>,
+                          ublas::compressed_matrix<double>, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float> compressed" << std::endl;
+    test_my_matrix_vector<ublas::compressed_vector<std::complex<float> >,
+                          ublas::compressed_matrix<std::complex<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double> compressed" << std::endl;
+    test_my_matrix_vector<ublas::compressed_vector<std::complex<double> >,
+                          ublas::compressed_matrix<std::complex<double> >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_COORDINATE_MATRIX
+#ifdef USE_FLOAT
+    std::cout << "float coordinate" << std::endl;
+    test_my_matrix_vector<ublas::coordinate_vector<float>,
+                          ublas::coordinate_matrix<float>, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double coordinate" << std::endl;
+    test_my_matrix_vector<ublas::coordinate_vector<double>,
+                          ublas::coordinate_matrix<double>, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float> coordinate" << std::endl;
+    test_my_matrix_vector<ublas::coordinate_vector<std::complex<float> >,
+                          ublas::coordinate_matrix<std::complex<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double> coordinate" << std::endl;
+    test_my_matrix_vector<ublas::coordinate_vector<std::complex<double> >,
+                          ublas::coordinate_matrix<std::complex<double> >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_MAPPED_VECTOR_OF_MAPPED_VECTOR
+#ifdef USE_STD_MAP
+#ifdef USE_FLOAT
+    std::cout << "float mapped_vector_of_mapped_vector" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >,
+                          ublas::mapped_vector_of_mapped_vector<float>, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double mapped_vector_of_mapped_vector" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >,
+                          ublas::mapped_vector_of_mapped_vector<double>, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float> mapped_vector_of_mapped_vector" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >,
+                          ublas::mapped_vector_of_mapped_vector<std::complex<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double> mapped_vector_of_mapped_vector" << std::endl;
+    test_my_matrix_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >,
+                          ublas::mapped_vector_of_mapped_vector<std::complex<double> >, 3 > () ();
+#endif
+#endif
+#endif
+#endif
+}
diff --git a/test/test33.cpp b/test/test33.cpp
new file mode 100644
index 0000000..b7d658c
--- /dev/null
+++ b/test/test33.cpp
@@ -0,0 +1,371 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test3.hpp"
+
+// Test matrix expression templates
+template<class M, std::size_t N>
+struct test_my_matrix {
+    typedef typename M::value_type value_type;
+
+    template<class MP>
+    void test_with (MP &m1, MP &m2, MP &m3) const {
+        {
+            value_type t;
+
+            // Default Construct
+            default_construct<MP>::test ();
+            
+            // Copy and swap
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m1 = m2;
+            std::cout << "m1 = m2 = " << m1 << std::endl;
+            m1.assign_temporary (m2);
+            std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl;
+            m1.swap (m2);
+            std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl;
+
+            // Zero assignment
+            m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ());
+            std::cout << "m1.zero_matrix = " << m1 << std::endl;
+            m1 = m2;
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+            // Project range and slice
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::range(0,1),ublas::range(0,1));
+            project (m1, ublas::range(0,1),ublas::range(0,1)) = project (m2, ublas::slice(0,1,1),ublas::slice(0,1,1));
+            project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::slice(0,1,2),ublas::slice(0,1,2));
+            project (m1, ublas::slice(2,-1,2),ublas::slice(2,-1,2)) = project (m2, ublas::range(0,2),ublas::range(0,2));
+            std::cout << "m1 = range/slice " << m1 << std::endl;
+#endif
+
+            // Unary matrix operations resulting in a matrix
+            initialize_matrix (m1);
+            m2 = - m1;
+            std::cout << "- m1 = " << m2 << std::endl;
+            m2 = ublas::conj (m1);
+            std::cout << "conj (m1) = " << m2 << std::endl;
+
+            // Binary matrix operations resulting in a matrix
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            initialize_matrix (m3);
+            m3 = m1 + m2;
+            std::cout << "m1 + m2 = " << m3 << std::endl;
+            m3 = m1 - m2;
+            std::cout << "m1 - m2 = " << m3 << std::endl;
+
+            // Scaling a matrix
+            t = N;
+            initialize_matrix (m1);
+            m2 = value_type (1.) * m1;
+            std::cout << "1. * m1 = " << m2 << std::endl;
+            m2 = t * m1;
+            std::cout << "N * m1 = " << m2 << std::endl;
+            initialize_matrix (m1);
+            m2 = m1 * value_type (1.);
+            std::cout << "m1 * 1. = " << m2 << std::endl;
+            m2 = m1 * t;
+            std::cout << "m1 * N = " << m2 << std::endl;
+
+            // Some assignments
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m2 += m1;
+            std::cout << "m2 += m1 = " << m2 << std::endl;
+            m2 -= m1;
+            std::cout << "m2 -= m1 = " << m2 << std::endl;
+            m2 = m2 + m1;
+            std::cout << "m2 = m2 + m1 = " << m2 << std::endl;
+            m2 = m2 - m1;
+            std::cout << "m2 = m2 - m1 = " << m2 << std::endl;
+            m1 *= value_type (1.);
+            std::cout << "m1 *= 1. = " << m1 << std::endl;
+            m1 *= t;
+            std::cout << "m1 *= N = " << m1 << std::endl;
+
+            // Transpose
+            initialize_matrix (m1);
+            m2 = ublas::trans (m1);
+            std::cout << "trans (m1) = " << m2 << std::endl;
+
+            // Hermitean
+            initialize_matrix (m1);
+            m2 = ublas::herm (m1);
+            std::cout << "herm (m1) = " << m2 << std::endl;
+
+            // Matrix multiplication
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m3 = ublas::prod (m1, m2);
+            std::cout << "prod (m1, m2) = " << m3 << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            M m1 (N, N, N * N), m2 (N, N, N * N), m3 (N, N, N * N);
+            test_with (m1, m2, m3);
+
+#ifdef USE_RANGE
+            ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                   mr2 (m2, ublas::range (0, N), ublas::range (0, N)),
+                                   mr3 (m3, ublas::range (0, N), ublas::range (0, N));
+            test_with (mr1, mr2, mr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                   ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                   ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (ms1, ms2, ms3);
+#endif
+        }
+    }
+};
+
+// Test matrix
+void test_matrix () {
+    std::cout << "test_matrix" << std::endl;
+
+#ifdef USE_SPARSE_MATRIX
+#ifdef USE_MAP_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, mapped_matrix map_array" << std::endl;
+    test_my_matrix<ublas::mapped_matrix<float, ublas::row_major, ublas::map_array<std::size_t, float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, mapped_matrix map_array" << std::endl;
+    test_my_matrix<ublas::mapped_matrix<double, ublas::row_major, ublas::map_array<std::size_t, double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, mapped_matrix map_array" << std::endl;
+    test_my_matrix<ublas::mapped_matrix<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, mapped_matrix map_array" << std::endl;
+    test_my_matrix<ublas::mapped_matrix<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_MAP
+#ifdef USE_FLOAT
+    std::cout << "float, mapped_matrix std::map" << std::endl;
+    test_my_matrix<ublas::mapped_matrix<float, ublas::row_major, std::map<std::size_t, float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, mapped_matrix std::map" << std::endl;
+    test_my_matrix<ublas::mapped_matrix<double, ublas::row_major, std::map<std::size_t, double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, mapped_matrix std::map" << std::endl;
+    test_my_matrix<ublas::mapped_matrix<std::complex<float>, ublas::row_major, std::map<std::size_t, std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, mapped_matrix std::map" << std::endl;
+    test_my_matrix<ublas::mapped_matrix<std::complex<double>, ublas::row_major, std::map<std::size_t, std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_SPARSE_VECTOR_OF_SPARSE_VECTOR
+#ifdef USE_MAP_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, mapped_vector_of_mapped_vector map_array" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<float, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, mapped_vector_of_mapped_vector map_array" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<double, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, double> > >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, mapped_vector_of_mapped_vector map_array" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<float>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<float> > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, mapped_vector_of_mapped_vectormap_array" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<double>, ublas::row_major, ublas::map_array<std::size_t, ublas::map_array<std::size_t, std::complex<double> > > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_MAP
+#ifdef USE_FLOAT
+    std::cout << "float, mapped_vector_of_mapped_vector std::map" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<float, ublas::row_major, std::map<std::size_t, std::map<std::size_t, float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, mapped_vector_of_mapped_vector std::map" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<double, ublas::row_major, std::map<std::size_t, std::map<std::size_t, double> > >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, mapped_vector_of_mapped_vector std::map" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<float>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<float> > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, mapped_vector_of_mapped_vector std::map" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<double>, ublas::row_major, std::map<std::size_t, std::map<std::size_t, std::complex<double> > > >, 3 > () ();
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_GENERALIZED_VECTOR_OF_VECTOR
+#ifdef USE_MAP_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float,generalized_vector_of_vector map_array" << std::endl;
+    test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > >, 3 > () ();
+    test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, ublas::map_array<std::size_t, float> >, ublas::map_array<std::size_t, ublas::mapped_vector<float, ublas::map_array<std::size_t, float> > > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, generalized_vector_of_vector map_array" << std::endl;
+    test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > >, 3 > () ();
+    test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, ublas::map_array<std::size_t, double> >, ublas::map_array<std::size_t, ublas::mapped_vector<double, ublas::map_array<std::size_t, double> > > > >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, generalized_vector_of_vector map_array" << std::endl;
+    test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > >, 3 > () ();
+    test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<float>, ublas::map_array<std::size_t, std::complex<float> > > > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, generalized_vector_of_vector map_array" << std::endl;
+    test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > >, 3 > () ();
+    test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > >, ublas::map_array<std::size_t, ublas::mapped_vector<std::complex<double>, ublas::map_array<std::size_t, std::complex<double> > > > > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_MAP
+#ifdef USE_FLOAT
+    std::cout << "float, generalized_vector_of_vector std::map" << std::endl;
+    test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::vector<ublas::mapped_vector<float, std::map<std::size_t, float> > > >, 3 > () ();
+    test_my_matrix<ublas::generalized_vector_of_vector<float, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<float, std::map<std::size_t, float> >, std::map<std::size_t, ublas::mapped_vector<float, std::map<std::size_t, float> > > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, generalized_vector_of_vector std::map" << std::endl;
+    test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::vector<ublas::mapped_vector<double, std::map<std::size_t, double> > > >, 3 > () ();
+    test_my_matrix<ublas::generalized_vector_of_vector<double, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<double, std::map<std::size_t, double> >, std::map<std::size_t, ublas::mapped_vector<double, std::map<std::size_t, double> > > > >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, generalized_vector_of_vector std::map" << std::endl;
+    test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > >, 3 > () ();
+    test_my_matrix<ublas::generalized_vector_of_vector<std::complex<float>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<float>, std::map<std::size_t, std::complex<float> > > > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, generalized_vector_of_vector std::map" << std::endl;
+    test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > >, 3 > () ();
+    test_my_matrix<ublas::generalized_vector_of_vector<std::complex<double>, ublas::row_major, ublas::mapped_vector<ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > >, std::map<std::size_t, ublas::mapped_vector<std::complex<double>, std::map<std::size_t, std::complex<double> > > > > >, 3 > () ();
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_COMPRESSED_MATRIX
+#ifdef USE_FLOAT
+    std::cout << "float compressed_matrix" << std::endl;
+    test_my_matrix<ublas::compressed_matrix<float>, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double compressed_matrix" << std::endl;
+    test_my_matrix<ublas::compressed_matrix<double>, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float> compressed_matrix" << std::endl;
+    test_my_matrix<ublas::compressed_matrix<std::complex<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double> compressed_matrix" << std::endl;
+    test_my_matrix<ublas::compressed_matrix<std::complex<double> >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_COORDINATE_MATRIX
+#ifdef USE_FLOAT
+    std::cout << "float coordinate_matrix" << std::endl;
+    test_my_matrix<ublas::coordinate_matrix<float>, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double coordinate_matrix" << std::endl;
+    test_my_matrix<ublas::coordinate_matrix<double>, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float> coordinate_matrix" << std::endl;
+    test_my_matrix<ublas::coordinate_matrix<std::complex<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double> coordinate_matrix" << std::endl;
+    test_my_matrix<ublas::coordinate_matrix<std::complex<double> >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_MAPPED_VECTOR_OF_MAPPED_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float mapped_vector_of_mapped_vector" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<float>, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double mapped_vector_of_mapped_vector" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<double>, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float> mapped_vector_of_mapped_vector" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double> mapped_vector_of_mapped_vector" << std::endl;
+    test_my_matrix<ublas::mapped_vector_of_mapped_vector<std::complex<double> >, 3 > () ();
+#endif
+#endif
+#endif
+}
diff --git a/test/test4.cpp b/test/test4.cpp
new file mode 100644
index 0000000..bf5816f
--- /dev/null
+++ b/test/test4.cpp
@@ -0,0 +1,19 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test4.hpp"
+
+int main () {
+    test_matrix_vector ();
+    test_matrix ();
+    return 0;
+}
diff --git a/test/test4.hpp b/test/test4.hpp
new file mode 100644
index 0000000..fc5b48c
--- /dev/null
+++ b/test/test4.hpp
@@ -0,0 +1,39 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef TEST4_H
+#define TEST4_H
+
+#include <iostream>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/banded.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+namespace ublas = boost::numeric::ublas;
+
+#include "common/init.hpp"
+
+//#define USE_BANDED
+#define USE_DIAGONAL
+
+
+void test_matrix_vector ();
+void test_matrix ();
+
+
+// FIXME slice are failing in assignment to zero elements
+#undef USE_SLICE
+
+#endif
diff --git a/test/test42.cpp b/test/test42.cpp
new file mode 100644
index 0000000..a1fd3f2
--- /dev/null
+++ b/test/test42.cpp
@@ -0,0 +1,361 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test4.hpp"
+
+// Test matrix & vector expression templates
+template<class V, class M, int N>
+struct test_my_matrix_vector {
+    typedef typename V::value_type value_type;
+
+    template<class VP, class MP>
+    void test_with (VP &v1, VP &v2, MP &m1) const {
+        {
+#ifndef USE_DIAGONAL
+            // Rows and columns
+            initialize_matrix (m1);
+            for (int i = 0; i < N; ++ i) {
+                v2 = ublas::row (m1, i);
+                std::cout << "row (m, " << i << ") = " << v2 << std::endl;
+                v2 = ublas::column (m1, i);
+                std::cout << "column (m, " << i << ") = " << v2 << std::endl;
+            }
+
+            // Outer product
+            initialize_vector (v1);
+            initialize_vector (v2);
+            v1 (0) = 0;
+            v1 (N - 1) = 0;
+            m1 = ublas::outer_prod (v1, v2);
+            std::cout << "outer_prod (v1, v2) = " << m1 << std::endl;
+
+            // Matrix vector product
+            initialize_matrix (m1);
+            initialize_vector (v1);
+            v2 = ublas::prod (m1, v1);
+            std::cout << "prod (m1, v1) = " << v2 << std::endl;
+            v2 = ublas::prod (v1, m1);
+            std::cout << "prod (v1, m1) = " << v2 << std::endl;
+#endif
+        }
+    }
+    void operator () () const {
+        {
+            V v1 (N), v2 (N);
+#ifdef USE_BANDED
+            M m1 (N, N, 1, 1);
+#endif
+#ifdef USE_DIAGONAL
+            M m1 (N, N);
+#endif
+            test_with (v1, v2, m1);
+
+            ublas::matrix_row<M> mr1 (m1, 1), mr2 (m1, 1);
+            test_with (mr1, mr2, m1);
+
+            ublas::matrix_column<M> mc1 (m1, 1), mc2 (m1, 1);
+            test_with (mc1, mc2, m1);
+
+#ifdef USE_RANGE
+            ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                          mvr2 (m1, ublas::range (0, N), ublas::range (0, N));
+            test_with (mvr1, mvr2, m1);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                          mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (mvs1, mvs2, m1);
+#endif
+        }
+    }
+
+    void operator () (int) const {
+#ifdef USE_ADAPTOR
+        {
+#ifdef USE_BANDED
+            V v1 (N), v2 (N);
+            M m1 (N, N, 1, 1);
+            ublas::banded_adaptor<M> bam1 (m1, 1, 1);
+            test_with (v1, v2, bam1);
+
+            ublas::matrix_row<ublas::banded_adaptor<M> > mr1 (bam1, 1), mr2 (bam1, 1);
+            test_with (mr1, mr2, bam1);
+
+            ublas::matrix_column<ublas::banded_adaptor<M> > mc1 (bam1, 1), mc2 (bam1, 1);
+            test_with (mc1, mc2, bam1);
+
+#ifdef USE_RANGE
+            ublas::matrix_vector_range<ublas::banded_adaptor<M> > mvr1 (bam1, ublas::range (0, N), ublas::range (0, N)),
+                                                                  mvr2 (bam1, ublas::range (0, N), ublas::range (0, N));
+            test_with (mvr1, mvr2, bam1);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_vector_slice<ublas::banded_adaptor<M> > mvs1 (bam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                                  mvs2 (bam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (mvs1, mvs2, bam1);
+#endif
+#endif
+#ifdef USE_DIAGONAL
+            V v1 (N), v2 (N);
+            M m1 (N, N);
+            ublas::diagonal_adaptor<M> dam1 (m1);
+            test_with (v1, v2, dam1);
+
+            ublas::matrix_row<ublas::diagonal_adaptor<M> > mr1 (dam1, 1), mr2 (dam1, 1);
+            test_with (mr1, mr2, dam1);
+
+            ublas::matrix_column<ublas::diagonal_adaptor<M> > mc1 (dam1, 1), mc2 (dam1, 1);
+            test_with (mc1, mc2, dam1);
+
+#ifdef USE_RANGE
+            ublas::matrix_vector_range<ublas::diagonal_adaptor<M> > mvr1 (dam1, ublas::range (0, N), ublas::range (0, N)),
+                                                                    mvr2 (dam1, ublas::range (0, N), ublas::range (0, N));
+            test_with (mvr1, mvr2, dam1);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_vector_slice<ublas::diagonal_adaptor<M> > mvs1 (dam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                                    mvs2 (dam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (mvs1, mvs2, dam1);
+#endif
+#endif
+        }
+#endif
+    }
+};
+
+// Test matrix & vector
+void test_matrix_vector () {
+    std::cout << "test_matrix_vector" << std::endl;
+
+#ifdef USE_BANDED
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >,
+                          ublas::banded_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >,
+                          ublas::banded_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >,
+                          ublas::banded_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >,
+                          ublas::banded_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >,
+                          ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >,
+                          ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >,
+                          ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >,
+                          ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0);
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >,
+                          ublas::banded_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >,
+                          ublas::banded_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >,
+                          ublas::banded_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >,
+                          ublas::banded_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >,
+                          ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >,
+                          ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >,
+                          ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >,
+                          ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0);
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, std::vector<float> >,
+                          ublas::banded_matrix<float, ublas::row_major, std::vector<float> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, std::vector<float> >,
+                          ublas::banded_matrix<float, ublas::row_major, std::vector<float> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, std::vector<double> >,
+                          ublas::banded_matrix<double, ublas::row_major, std::vector<double> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, std::vector<double> >,
+                          ublas::banded_matrix<double, ublas::row_major, std::vector<double> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >,
+                          ublas::banded_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >,
+                          ublas::banded_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >,
+                          ublas::banded_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >,
+                          ublas::banded_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0);
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_DIAGONAL
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >,
+                          ublas::diagonal_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >,
+                          ublas::diagonal_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >,
+                          ublas::diagonal_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >,
+                          ublas::diagonal_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >,
+                          ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >,
+                          ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >,
+                          ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >,
+                          ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0);
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >,
+                          ublas::diagonal_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >,
+                          ublas::diagonal_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >,
+                          ublas::diagonal_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >,
+                          ublas::diagonal_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >,
+                          ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >,
+                          ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >,
+                          ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >,
+                          ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0);
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, std::vector<float> >,
+                          ublas::diagonal_matrix<float, ublas::row_major, std::vector<float> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, std::vector<float> >,
+                          ublas::diagonal_matrix<float, ublas::row_major, std::vector<float> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, std::vector<double> >,
+                          ublas::diagonal_matrix<double, ublas::row_major, std::vector<double> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, std::vector<double> >,
+                          ublas::diagonal_matrix<double, ublas::row_major, std::vector<double> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >,
+                          ublas::diagonal_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >,
+                          ublas::diagonal_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >,
+                          ublas::diagonal_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >,
+                          ublas::diagonal_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0);
+#endif
+#endif
+#endif
+#endif
+}
diff --git a/test/test43.cpp b/test/test43.cpp
new file mode 100644
index 0000000..9db3c9b
--- /dev/null
+++ b/test/test43.cpp
@@ -0,0 +1,326 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test4.hpp"
+
+// Test matrix expression templates
+template<class M, int N>
+struct test_my_matrix {
+    typedef typename M::value_type value_type;
+
+    template<class MP>
+    void test_with (MP &m1, MP &m2, MP &m3) const {
+        {
+            value_type t;
+
+            // Default Construct
+            default_construct<MP>::test ();
+            
+            // Copy and swap
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m1 = m2;
+            std::cout << "m1 = m2 = " << m1 << std::endl;
+            m1.assign_temporary (m2);
+            std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl;
+            m1.swap (m2);
+            std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl;
+
+            // Zero assignment
+            m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ());
+            std::cout << "m1.zero_matrix = " << m1 << std::endl;
+            m1 = m2;
+
+            // Unary matrix operations resulting in a matrix
+            initialize_matrix (m1);
+            m2 = - m1;
+            std::cout << "- m1 = " << m2 << std::endl;
+            m2 = ublas::conj (m1);
+            std::cout << "conj (m1) = " << m2 << std::endl;
+
+            // Binary matrix operations resulting in a matrix
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m3 = m1 + m2;
+            std::cout << "m1 + m2 = " << m3 << std::endl;
+            m3 = m1 - m2;
+            std::cout << "m1 - m2 = " << m3 << std::endl;
+
+            // Scaling a matrix
+            t = N;
+            initialize_matrix (m1);
+            m2 = value_type (1.) * m1;
+            std::cout << "1. * m1 = " << m2 << std::endl;
+            m2 = t * m1;
+            std::cout << "N * m1 = " << m2 << std::endl;
+            initialize_matrix (m1);
+            m2 = m1 * value_type (1.);
+            std::cout << "m1 * 1. = " << m2 << std::endl;
+            m2 = m1 * t;
+            std::cout << "m1 * N = " << m2 << std::endl;
+
+            // Some assignments
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m2 += m1;
+            std::cout << "m2 += m1 = " << m2 << std::endl;
+            m2 -= m1;
+            std::cout << "m2 -= m1 = " << m2 << std::endl;
+            m2 = m2 + m1;
+            std::cout << "m2 = m2 + m1 = " << m2 << std::endl;
+            m2 = m2 - m1;
+            std::cout << "m2 = m2 - m1 = " << m2 << std::endl;
+            m1 *= value_type (1.);
+            std::cout << "m1 *= 1. = " << m1 << std::endl;
+            m1 *= t;
+            std::cout << "m1 *= N = " << m1 << std::endl;
+
+            // Transpose
+            initialize_matrix (m1);
+            m2 = ublas::trans (m1);
+            std::cout << "trans (m1) = " << m2 << std::endl;
+
+            // Hermitean
+            initialize_matrix (m1);
+            m2 = ublas::herm (m1);
+            std::cout << "herm (m1) = " << m2 << std::endl;
+
+            // Matrix multiplication
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            // Banded times banded isn't banded
+            std::cout << "prod (m1, m2) = " << ublas::prod (m1, m2) << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+#ifdef USE_BANDED
+            M m1 (N, N, 1, 1), m2 (N, N, 1, 1), m3 (N, N, 1, 1);
+#endif
+#ifdef USE_DIAGONAL
+            M m1 (N, N), m2 (N, N), m3 (N, N);
+#endif
+            test_with (m1, m2, m3);
+
+#ifdef USE_RANGE
+            ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                   mr2 (m2, ublas::range (0, N), ublas::range (0, N)),
+                                   mr3 (m3, ublas::range (0, N), ublas::range (0, N));
+            test_with (mr1, mr2, mr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                   ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                   ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (ms1, ms2, ms3);
+#endif
+        }
+
+#ifdef USE_ADAPTOR
+        {
+#ifdef USE_BANDED
+            M m1 (N, N, 1, 1), m2 (N, N, 1, 1), m3 (N, N, 1, 1);
+            ublas::banded_adaptor<M> bam1 (m1, 1, 1), bam2 (m2, 1, 1), bam3 (m3, 1, 1);
+            test_with (bam1, bam2, bam3);
+
+#ifdef USE_RANGE
+            ublas::matrix_range<ublas::banded_adaptor<M> > mr1 (bam1, ublas::range (0, N), ublas::range (0, N)),
+                                                           mr2 (bam2, ublas::range (0, N), ublas::range (0, N)),
+                                                           mr3 (bam3, ublas::range (0, N), ublas::range (0, N));
+            test_with (mr1, mr2, mr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_slice<ublas::banded_adaptor<M> > ms1 (bam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                           ms2 (bam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                           ms3 (bam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (ms1, ms2, ms3);
+#endif
+#endif
+#ifdef USE_DIAGONAL
+            M m1 (N, N), m2 (N, N), m3 (N, N);
+            ublas::diagonal_adaptor<M> dam1 (m1), dam2 (m2), dam3 (m3);
+            test_with (dam1, dam2, dam3);
+
+#ifdef USE_RANGE
+            ublas::matrix_range<ublas::diagonal_adaptor<M> > mr1 (dam1, ublas::range (0, N), ublas::range (0, N)),
+                                                             mr2 (dam2, ublas::range (0, N), ublas::range (0, N)),
+                                                             mr3 (dam3, ublas::range (0, N), ublas::range (0, N));
+            test_with (mr1, mr2, mr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_slice<ublas::diagonal_adaptor<M> > ms1 (dam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                             ms2 (dam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                             ms3 (dam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (ms1, ms2, ms3);
+#endif
+#endif
+        }
+#endif
+
+    }
+};
+
+// Test matrix
+void test_matrix () {
+    std::cout << "test_matrix" << std::endl;
+
+#ifdef USE_BANDED
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix<ublas::banded_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix<ublas::banded_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix<ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix<ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix<ublas::banded_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix<ublas::banded_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::banded_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::banded_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix<ublas::banded_matrix<float, ublas::row_major, std::vector<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix<ublas::banded_matrix<double, ublas::row_major, std::vector<double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix<ublas::banded_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix<ublas::banded_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+#endif
+
+#ifdef USE_DIAGONAL
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<float, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<double, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<float, ublas::row_major, ublas::unbounded_array<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<double, ublas::row_major, ublas::unbounded_array<double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<std::complex<float>, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<std::complex<double>, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<float, ublas::row_major, std::vector<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<double, ublas::row_major, std::vector<double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<std::complex<float>, ublas::row_major, std::vector<std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix<ublas::diagonal_matrix<std::complex<double>, ublas::row_major, std::vector<std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+#endif
+}
diff --git a/test/test5.cpp b/test/test5.cpp
new file mode 100644
index 0000000..548cd60
--- /dev/null
+++ b/test/test5.cpp
@@ -0,0 +1,19 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test5.hpp"
+
+int main () {
+    test_matrix_vector ();
+    test_matrix ();
+    return 0;
+}
diff --git a/test/test5.hpp b/test/test5.hpp
new file mode 100644
index 0000000..a13dfa2
--- /dev/null
+++ b/test/test5.hpp
@@ -0,0 +1,35 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef TEST5_H
+#define TEST5_H
+
+#include <iostream>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+namespace ublas = boost::numeric::ublas;
+
+#include "common/init.hpp"
+
+void test_matrix_vector ();
+void test_matrix ();
+
+
+// FIXME slice are failing in assignment to zero elements
+#undef USE_SLICE
+
+#endif
diff --git a/test/test52.cpp b/test/test52.cpp
new file mode 100644
index 0000000..4803ce2
--- /dev/null
+++ b/test/test52.cpp
@@ -0,0 +1,214 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test5.hpp"
+
+// Test matrix & vector expression templates
+template<class V, class M, int N>
+struct test_my_matrix_vector {
+    typedef typename V::value_type value_type;
+
+    template<class VP, class MP>
+    void test_with (VP &v1, VP &v2, MP &m1) const {
+        {
+            // Rows and columns
+            initialize_matrix (m1);
+            for (int i = 0; i < N; ++ i) {
+                v2 = ublas::row (m1, i);
+                std::cout << "row (m, " << i << ") = " << v2 << std::endl;
+                v2 = ublas::column (m1, i);
+                std::cout << "column (m, " << i << ") = " << v2 << std::endl;
+            }
+
+            // Outer product
+            initialize_vector (v1);
+            initialize_vector (v2);
+            v1 (0) = 0;
+            v2 (N - 1) = 0;
+            m1 = ublas::outer_prod (v1, v2);
+            std::cout << "outer_prod (v1, v2) = " << m1 << std::endl;
+
+            // Matrix vector product
+            initialize_matrix (m1);
+            initialize_vector (v1);
+            v2 = ublas::prod (m1, v1);
+            std::cout << "prod (m1, v1) = " << v2 << std::endl;
+            v2 = ublas::prod (v1, m1);
+            std::cout << "prod (v1, m1) = " << v2 << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            V v1 (N), v2 (N);
+            M m1 (N, N);
+            test_with (v1, v2, m1);
+
+            ublas::matrix_row<M> mr1 (m1, N - 1), mr2 (m1, N - 1);
+            test_with (mr1, mr2, m1);
+
+            ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 0);
+            test_with (mc1, mc2, m1);
+
+#ifdef USE_RANGE
+            ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                          mvr2 (m1, ublas::range (0, N), ublas::range (0, N));
+            test_with (mvr1, mvr2, m1);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                          mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (mvs1, mvs2, m1);
+#endif
+        }
+    }
+
+    void operator () (int) const {
+#ifdef USE_ADAPTOR
+        {
+            V v1 (N), v2 (N);
+            M m1 (N, N);
+            ublas::triangular_adaptor<M> tam1 (m1);
+            test_with (v1, v2, tam1);
+
+            ublas::matrix_row<ublas::triangular_adaptor<M> > mr1 (tam1, N - 1), mr2 (tam1, N - 1);
+            test_with (mr1, mr2, tam1);
+
+            ublas::matrix_column<ublas::triangular_adaptor<M> > mc1 (tam1, 0), mc2 (tam1, 0);
+            test_with (mc1, mc2, tam1);
+
+#ifdef USE_RANGE
+            ublas::matrix_vector_range<ublas::triangular_adaptor<M> > mvr1 (tam1, ublas::range (0, N), ublas::range (0, N)),
+                                                                      mvr2 (tam1, ublas::range (0, N), ublas::range (0, N));
+            test_with (mvr1, mvr2, tam1);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_vector_slice<ublas::triangular_adaptor<M> > mvs1 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                                      mvs2 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (mvs1, mvs2, tam1);
+#endif
+        }
+#endif
+    }
+};
+
+// Test matrix & vector
+void test_matrix_vector () {
+    std::cout << "test_matrix_vector" << std::endl;
+
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >,
+                          ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >,
+                          ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >,
+                          ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >,
+                          ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >,
+                          ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >,
+                          ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >,
+                          ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >,
+                          ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0);
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >,
+                          ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >,
+                          ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >,
+                          ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >,
+                          ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >,
+                          ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >,
+                          ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >,
+                          ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >,
+                          ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0);
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, std::vector<float> >,
+                          ublas::triangular_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, std::vector<float> >,
+                          ublas::triangular_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, std::vector<double> >,
+                          ublas::triangular_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, std::vector<double> >,
+                          ublas::triangular_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >,
+                          ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >,
+                          ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0);
+
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >,
+                          ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >,
+                          ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0);
+#endif
+#endif
+#endif
+}
diff --git a/test/test53.cpp b/test/test53.cpp
new file mode 100644
index 0000000..250d462
--- /dev/null
+++ b/test/test53.cpp
@@ -0,0 +1,223 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test5.hpp"
+
+// Test matrix expression templates
+template<class M, int N>
+struct test_my_matrix {
+    typedef typename M::value_type value_type;
+
+    template<class MP>
+    void test_with (MP &m1, MP &m2, MP &m3) const {
+        {
+            value_type t;
+
+            // Default Construct
+            default_construct<MP>::test ();
+            
+            // Copy and swap
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m1 = m2;
+            std::cout << "m1 = m2 = " << m1 << std::endl;
+            m1.assign_temporary (m2);
+            std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl;
+            m1.swap (m2);
+            std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl;
+
+            // Zero assignment
+            m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ());
+            std::cout << "m1.zero_matrix = " << m1 << std::endl;
+            m1 = m2;
+
+            // Unary matrix operations resulting in a matrix
+            initialize_matrix (m1);
+            m2 = - m1;
+            std::cout << "- m1 = " << m2 << std::endl;
+            m2 = ublas::conj (m1);
+            std::cout << "conj (m1) = " << m2 << std::endl;
+
+            // Binary matrix operations resulting in a matrix
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m3 = m1 + m2;
+            std::cout << "m1 + m2 = " << m3 << std::endl;
+            m3 = m1 - m2;
+            std::cout << "m1 - m2 = " << m3 << std::endl;
+
+            // Scaling a matrix
+            t = N;
+            initialize_matrix (m1);
+            m2 = value_type (1.) * m1;
+            std::cout << "1. * m1 = " << m2 << std::endl;
+            m2 = t * m1;
+            std::cout << "N * m1 = " << m2 << std::endl;
+            initialize_matrix (m1);
+            m2 = m1 * value_type (1.);
+            std::cout << "m1 * 1. = " << m2 << std::endl;
+            m2 = m1 * t;
+            std::cout << "m1 * N = " << m2 << std::endl;
+
+            // Some assignments
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m2 += m1;
+            std::cout << "m2 += m1 = " << m2 << std::endl;
+            m2 -= m1;
+            std::cout << "m2 -= m1 = " << m2 << std::endl;
+            m2 = m2 + m1;
+            std::cout << "m2 = m2 + m1 = " << m2 << std::endl;
+            m2 = m2 - m1;
+            std::cout << "m2 = m2 - m1 = " << m2 << std::endl;
+            m1 *= value_type (1.);
+            std::cout << "m1 *= 1. = " << m1 << std::endl;
+            m1 *= t;
+            std::cout << "m1 *= N = " << m1 << std::endl;
+
+            // Transpose
+            initialize_matrix (m1);
+            // Transpose of a triangular isn't triangular of the same kind
+            std::cout << "trans (m1) = " << ublas::trans (m1) << std::endl;
+
+            // Hermitian
+            initialize_matrix (m1);
+            // Hermitian of a triangular isn't hermitian of the same kind
+            std::cout << "herm (m1) = " << ublas::herm (m1) << std::endl;
+
+            // Matrix multiplication
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m3 = ublas::prod (m1, m2);
+            std::cout << "prod (m1, m2) = " << m3 << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            M m1 (N, N), m2 (N, N), m3 (N, N);
+            test_with (m1, m2, m3);
+
+#ifdef USE_RANGE
+            ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                   mr2 (m2, ublas::range (0, N), ublas::range (0, N)),
+                                   mr3 (m3, ublas::range (0, N), ublas::range (0, N));
+            test_with (mr1, mr2, mr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                   ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                   ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (ms1, ms2, ms3);
+#endif
+        }
+
+#ifdef USE_ADAPTOR
+        {
+            M m1 (N, N), m2 (N, N), m3 (N, N);
+            ublas::triangular_adaptor<M> tam1 (m1), tam2 (m2), tam3 (m3);
+            test_with (tam1, tam2, tam3);
+
+#ifdef USE_RANGE
+            ublas::matrix_range<ublas::triangular_adaptor<M> > mr1 (tam1, ublas::range (0, N), ublas::range (0, N)),
+                                                               mr2 (tam2, ublas::range (0, N), ublas::range (0, N)),
+                                                               mr3 (tam3, ublas::range (0, N), ublas::range (0, N));
+            test_with (mr1, mr2, mr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_slice<ublas::triangular_adaptor<M> > ms1 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                               ms2 (tam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                               ms3 (tam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (ms1, ms2, ms3);
+#endif
+        }
+#endif
+    }
+};
+
+// Test matrix
+void test_matrix () {
+    std::cout << "test_matrix" << std::endl;
+
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix<ublas::triangular_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+}
diff --git a/test/test6.cpp b/test/test6.cpp
new file mode 100644
index 0000000..61a5c31
--- /dev/null
+++ b/test/test6.cpp
@@ -0,0 +1,19 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test6.hpp"
+
+int main () {
+    test_matrix_vector ();
+    test_matrix ();
+    return 0;
+}
diff --git a/test/test6.hpp b/test/test6.hpp
new file mode 100644
index 0000000..766d6b9
--- /dev/null
+++ b/test/test6.hpp
@@ -0,0 +1,32 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef TEST6_H
+#define TEST6_H
+
+#include <iostream>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/symmetric.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+namespace ublas = boost::numeric::ublas;
+
+#include "common/init.hpp"
+
+void test_matrix_vector ();
+void test_matrix ();
+
+
+#endif
diff --git a/test/test62.cpp b/test/test62.cpp
new file mode 100644
index 0000000..5d7feb9
--- /dev/null
+++ b/test/test62.cpp
@@ -0,0 +1,218 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test6.hpp"
+
+// Test matrix & vector expression templates
+template<class V, class M, int N>
+struct test_my_matrix_vector {
+    typedef typename V::value_type value_type;
+
+    template<class VP, class MP>
+    void test_with (VP &v1, VP &v2, MP &m1) const {
+        {
+            // Rows and columns
+            initialize_matrix (m1);
+            for (int i = 0; i < N; ++ i) {
+                v2 = ublas::row (m1, i);
+                std::cout << "row (m, " << i << ") = " << v2 << std::endl;
+                v2 = ublas::column (m1, i);
+                std::cout << "column (m, " << i << ") = " << v2 << std::endl;
+            }
+
+            // Outer product
+            initialize_vector (v1);
+            initialize_vector (v2);
+            v1 (0) = 0;
+            v1 (N - 1) = 0;
+            v2 (0) = 0;
+            v2 (N - 1) = 0;
+            m1 = ublas::outer_prod (v1, v2);
+            std::cout << "outer_prod (v1, v2) = " << m1 << std::endl;
+
+            // Matrix vector product
+            initialize_matrix (m1);
+            initialize_vector (v1);
+            v2 = ublas::prod (m1, v1);
+            std::cout << "prod (m1, v1) = " << v2 << std::endl;
+            v2 = ublas::prod (v1, m1);
+            std::cout << "prod (v1, m1) = " << v2 << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            V v1 (N), v2 (N);
+            M m1 (N, N);
+            test_with (v1, v2, m1);
+
+            ublas::matrix_row<M> mr1 (m1, N - 1), mr2 (m1, N - 1);
+            test_with (mr1, mr2, m1);
+
+            ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 0);
+            test_with (mc1, mc2, m1);
+
+#ifdef USE_RANGE
+            ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                          mvr2 (m1, ublas::range (0, N), ublas::range (0, N));
+            test_with (mvr1, mvr2, m1);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                          mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (mvs1, mvs2, m1);
+#endif
+        }
+    }
+
+    void operator () (int) const {
+#ifdef USE_ADAPTOR
+        {
+            V v1 (N), v2 (N);
+            M m1 (N, N);
+            ublas::symmetric_adaptor<M> tam1 (m1);
+            test_with (v1, v2, tam1);
+
+            ublas::matrix_row<ublas::symmetric_adaptor<M> > mr1 (tam1, N - 1), mr2 (tam1, N - 1);
+            test_with (mr1, mr2, tam1);
+
+            ublas::matrix_column<ublas::symmetric_adaptor<M> > mc1 (tam1, 0), mc2 (tam1, 0);
+            test_with (mc1, mc2, tam1);
+
+#ifdef USE_RANGE
+            ublas::matrix_vector_range<ublas::symmetric_adaptor<M> > mvr1 (tam1, ublas::range (0, N), ublas::range (0, N)),
+                                                                     mvr2 (tam1, ublas::range (0, N), ublas::range (0, N));
+            test_with (mvr1, mvr2, tam1);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_vector_slice<ublas::symmetric_adaptor<M> > mvs1 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                                     mvs2 (tam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (mvs1, mvs2, tam1);
+#endif
+        }
+#endif
+    }
+};
+
+// Test matrix & vector
+void test_matrix_vector () {
+    std::cout << "test_matrix_vector" << std::endl;
+
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >,
+                          ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, ublas::bounded_array<float, 3> >,
+                          ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >,
+                          ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, ublas::bounded_array<double, 3> >,
+                          ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >,
+                          ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::bounded_array<std::complex<float>, 3> >,
+                          ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >,
+                          ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::bounded_array<std::complex<double>, 3> >,
+                          ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3> () (0);
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >,
+                          ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, ublas::unbounded_array<float> >,
+                          ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >,
+                          ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, ublas::unbounded_array<double> >,
+                          ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >,
+                          ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, ublas::unbounded_array<std::complex<float> > >,
+                          ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >,
+                          ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, ublas::unbounded_array<std::complex<double> > >,
+                          ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3> () (0);
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<float, std::vector<float> >,
+                          ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<float, std::vector<float> >,
+                          ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<double, std::vector<double> >,
+                          ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () ();
+    test_my_matrix_vector<ublas::vector<double, std::vector<double> >,
+                          ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3> () (0);
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >,
+                          ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<float>, std::vector<std::complex<float> > >,
+                          ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3> () (0);
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >,
+                          ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () ();
+    test_my_matrix_vector<ublas::vector<std::complex<double>, std::vector<std::complex<double> > >,
+                          ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3> () (0);
+#endif
+#endif
+#endif
+}
diff --git a/test/test63.cpp b/test/test63.cpp
new file mode 100644
index 0000000..4a0013d
--- /dev/null
+++ b/test/test63.cpp
@@ -0,0 +1,223 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test6.hpp"
+
+// Test matrix expression templates
+template<class M, int N>
+struct test_my_matrix {
+    typedef typename M::value_type value_type;
+
+    template<class MP>
+    void test_with (MP &m1, MP &m2, MP &m3) const {
+        {
+            value_type t;
+
+            // Default Construct
+            default_construct<MP>::test ();
+            
+            // Copy and swap
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m1 = m2;
+            std::cout << "m1 = m2 = " << m1 << std::endl;
+            m1.assign_temporary (m2);
+            std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl;
+            m1.swap (m2);
+            std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl;
+
+            // Zero assignment
+            m1 = ublas::zero_matrix<> (m1.size1 (), m1.size2 ());
+            std::cout << "m1.zero_matrix = " << m1 << std::endl;
+            m1 = m2;
+
+            // Unary matrix operations resulting in a matrix
+            initialize_matrix (m1);
+            m2 = - m1;
+            std::cout << "- m1 = " << m2 << std::endl;
+            m2 = ublas::conj (m1);
+            std::cout << "conj (m1) = " << m2 << std::endl;
+
+            // Binary matrix operations resulting in a matrix
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m3 = m1 + m2;
+            std::cout << "m1 + m2 = " << m3 << std::endl;
+            m3 = m1 - m2;
+            std::cout << "m1 - m2 = " << m3 << std::endl;
+
+            // Scaling a matrix
+            t = N;
+            initialize_matrix (m1);
+            m2 = value_type (1.) * m1;
+            std::cout << "1. * m1 = " << m2 << std::endl;
+            m2 = t * m1;
+            std::cout << "N * m1 = " << m2 << std::endl;
+            initialize_matrix (m1);
+            m2 = m1 * value_type (1.);
+            std::cout << "m1 * 1. = " << m2 << std::endl;
+            m2 = m1 * t;
+            std::cout << "m1 * N = " << m2 << std::endl;
+
+            // Some assignments
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m2 += m1;
+            std::cout << "m2 += m1 = " << m2 << std::endl;
+            m2 -= m1;
+            std::cout << "m2 -= m1 = " << m2 << std::endl;
+            m2 = m2 + m1;
+            std::cout << "m2 = m2 + m1 = " << m2 << std::endl;
+            m2 = m2 - m1;
+            std::cout << "m2 = m1 - m1 = " << m2 << std::endl;
+            m1 *= value_type (1.);
+            std::cout << "m1 *= 1. = " << m1 << std::endl;
+            m1 *= t;
+            std::cout << "m1 *= N = " << m1 << std::endl;
+
+            // Transpose
+            initialize_matrix (m1);
+            m2 = ublas::trans (m1);
+            std::cout << "trans (m1) = " << m2 << std::endl;
+
+            // Hermitean
+            initialize_matrix (m1);
+            m2 = ublas::herm (m1);
+            std::cout << "herm (m1) = " << m2 << std::endl;
+
+            // Matrix multiplication
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m3 = ublas::prod (m1, m2);
+            std::cout << "prod (m1, m2) = " << m3 << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            M m1 (N, N), m2 (N, N), m3 (N, N);
+            test_with (m1, m2, m3);
+
+#ifdef USE_RANGE
+            ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                   mr2 (m2, ublas::range (0, N), ublas::range (0, N)),
+                                   mr3 (m3, ublas::range (0, N), ublas::range (0, N));
+            test_with (mr1, mr2, mr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                   ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                   ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (ms1, ms2, ms3);
+#endif
+        }
+
+#ifdef USE_ADAPTOR
+        {
+            M m1 (N, N), m2 (N, N), m3 (N, N);
+            ublas::symmetric_adaptor<M> sam1 (m1), sam2 (m2), sam3 (m3);
+            test_with (sam1, sam2, sam3);
+
+#ifdef USE_RANGE
+            ublas::matrix_range<ublas::symmetric_adaptor<M> > mr1 (sam1, ublas::range (0, N), ublas::range (0, N)),
+                                                              mr2 (sam2, ublas::range (0, N), ublas::range (0, N)),
+                                                              mr3 (sam3, ublas::range (0, N), ublas::range (0, N));
+            test_with (mr1, mr2, mr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_slice<ublas::symmetric_adaptor<M> > ms1 (sam1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                              ms2 (sam2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                                              ms3 (sam3, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (ms1, ms2, ms3);
+#endif
+        }
+#endif
+    }
+};
+
+// Test matrix
+void test_matrix () {
+    std::cout << "test_matrix" << std::endl;
+
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, bounded_array" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::bounded_array<float, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, bounded_array" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::bounded_array<double, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, bounded_array" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<float>, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, bounded_array" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::bounded_array<std::complex<double>, 3 * 3> >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "float, unbounded_array" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, ublas::unbounded_array<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, unbounded_array" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, ublas::unbounded_array<double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, ublas::unbounded_array<std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "float, std::vector" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<float, ublas::lower, ublas::row_major, std::vector<float> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "double, std::vector" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<double, ublas::lower, ublas::row_major, std::vector<double> >, 3 > () ();
+#endif
+
+#ifdef USE_STD_COMPLEX
+#ifdef USE_FLOAT
+    std::cout << "std::complex<float>, std::vector" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<std::complex<float>, ublas::lower, ublas::row_major, std::vector<std::complex<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "std::complex<double>, std::vector" << std::endl;
+    test_my_matrix<ublas::symmetric_matrix<std::complex<double>, ublas::lower, ublas::row_major, std::vector<std::complex<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+}
diff --git a/test/test7.cpp b/test/test7.cpp
new file mode 100644
index 0000000..f564031
--- /dev/null
+++ b/test/test7.cpp
@@ -0,0 +1,31 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include <iostream>
+
+#include <boost/numeric/interval.hpp>
+#include <boost/numeric/interval/io.hpp>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+#include "test7.hpp"
+
+// this testcase requires fix of task #2473 
+
+int main () {
+    test_vector ();
+    test_matrix_vector ();
+    test_matrix ();
+    return 0;
+}
diff --git a/test/test7.hpp b/test/test7.hpp
new file mode 100644
index 0000000..5dbae1f
--- /dev/null
+++ b/test/test7.hpp
@@ -0,0 +1,36 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#ifndef TEST7_H
+#define TEST7_H
+
+#include <iostream>
+
+#include <boost/numeric/interval.hpp>
+#include <boost/numeric/interval/io.hpp>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+namespace ublas = boost::numeric::ublas;
+
+#include "common/init.hpp"
+
+void test_vector ();
+void test_matrix_vector ();
+void test_matrix ();
+
+
+#endif
diff --git a/test/test71.cpp b/test/test71.cpp
new file mode 100644
index 0000000..89e9ccf
--- /dev/null
+++ b/test/test71.cpp
@@ -0,0 +1,170 @@
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test7.hpp"
+
+// Test vector expression templates
+template<class V, int N>
+struct test_my_vector {
+    typedef typename V::value_type value_type;
+    typedef typename V::size_type size_type;
+    typedef typename ublas::type_traits<value_type>::real_type real_type;
+
+    template<class VP>
+    void test_with (VP &v1, VP &v2, VP &v3) const {
+        {
+            value_type t;
+            size_type i;
+            real_type n;
+
+            // Copy and swap
+            initialize_vector (v1);
+            initialize_vector (v2);
+            v1 = v2;
+            std::cout << "v1 = v2 = " << v1 << std::endl;
+            v1.assign_temporary (v2);
+            std::cout << "v1.assign_temporary (v2) = " << v1 << std::endl;
+            v1.swap (v2);
+            std::cout << "v1.swap (v2) = " << v1 << " " << v2 << std::endl;
+
+            // Zero assignment
+            v1 = ublas::zero_vector<value_type> (v1.size ());
+            std::cout << "v1.zero_vector = " << v1 << std::endl;
+            v1 = v2;
+
+            // Unary vector operations resulting in a vector
+            initialize_vector (v1);
+            v2 = - v1;
+            std::cout << "- v1 = " << v2 << std::endl;
+            v2 = ublas::conj (v1);
+            std::cout << "conj (v1) = " << v2 << std::endl;
+
+            // Binary vector operations resulting in a vector
+            initialize_vector (v1);
+            initialize_vector (v2);
+            v3 = v1 + v2;
+            std::cout << "v1 + v2 = " << v3 << std::endl;
+
+            v3 = v1 - v2;
+            std::cout << "v1 - v2 = " << v3 << std::endl;
+
+            // Scaling a vector
+            t = value_type (N);
+            initialize_vector (v1);
+            v2 = value_type (1.) * v1;
+            std::cout << "1. * v1 = " << v2 << std::endl;
+//            v2 = t * v1;
+            std::cout << "N * v1 = " << v2 << std::endl;
+            initialize_vector (v1);
+//            v2 = v1 * value_type (1.);
+            std::cout << "v1 * 1. = " << v2 << std::endl;
+//            v2 = v1 * t;
+            std::cout << "v1 * N = " << v2 << std::endl;
+
+            // Some assignments
+            initialize_vector (v1);
+            initialize_vector (v2);
+            v2 += v1;
+            std::cout << "v2 += v1 = " << v2 << std::endl;
+            v2 -= v1;
+            std::cout << "v2 -= v1 = " << v2 << std::endl;
+            v2 = v2 + v1;
+            std::cout << "v2 = v2 + v1 = " << v2 << std::endl;
+            v2 = v2 - v1;
+            std::cout << "v2 = v2 - v1 = " << v2 << std::endl;
+            v1 *= value_type (1.);
+            std::cout << "v1 *= 1. = " << v1 << std::endl;
+            v1 *= t;
+            std::cout << "v1 *= N = " << v1 << std::endl;
+
+            // Unary vector operations resulting in a scalar
+            initialize_vector (v1);
+            t = ublas::sum (v1);
+            std::cout << "sum (v1) = " << t << std::endl;
+            n = ublas::norm_1 (v1);
+            std::cout << "norm_1 (v1) = " << n << std::endl;
+            n = ublas::norm_2 (v1);
+            std::cout << "norm_2 (v1) = " << n << std::endl;
+            n = ublas::norm_inf (v1);
+            std::cout << "norm_inf (v1) = " << n << std::endl;
+
+            i = ublas::index_norm_inf (v1);
+            std::cout << "index_norm_inf (v1) = " << i << std::endl;
+
+            // Binary vector operations resulting in a scalar
+            initialize_vector (v1);
+            initialize_vector (v2);
+            t = ublas::inner_prod (v1, v2);
+            std::cout << "inner_prod (v1, v2) = " << t << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            V v1 (N), v2 (N), v3 (N);
+            test_with (v1, v2, v3);
+
+#ifdef USE_RANGE
+            ublas::vector_range<V> vr1 (v1, ublas::range (0, N)),
+                                   vr2 (v2, ublas::range (0, N)),
+                                   vr3 (v3, ublas::range (0, N));
+            test_with (vr1, vr2, vr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::vector_slice<V> vs1 (v1, ublas::slice (0, 1, N)),
+                                   vs2 (v2, ublas::slice (0, 1, N)),
+                                   vs3 (v3, ublas::slice (0, 1, N));
+            test_with (vs1, vs2, vs3);
+#endif
+        }
+    }
+};
+
+// Test vector
+void test_vector () {
+    std::cout << "test_vector" << std::endl;
+
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl;
+    test_my_vector<ublas::vector<boost::numeric::interval<float>, ublas::bounded_array<boost::numeric::interval<float>, 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl;
+    test_my_vector<ublas::vector<boost::numeric::interval<double>, ublas::bounded_array<boost::numeric::interval<double>, 3> >, 3 > () ();
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl;
+    test_my_vector<ublas::vector<boost::numeric::interval<float>, ublas::unbounded_array<boost::numeric::interval<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl;
+    test_my_vector<ublas::vector<boost::numeric::interval<double>, ublas::unbounded_array<boost::numeric::interval<double> > >, 3 > () ();
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, std::vector" << std::endl;
+    test_my_vector<ublas::vector<boost::numeric::interval<float>, std::vector<boost::numeric::interval<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, std::vector" << std::endl;
+    test_my_vector<ublas::vector<boost::numeric::interval<double>, std::vector<boost::numeric::interval<double> > >, 3 > () ();
+#endif
+#endif
+}
diff --git a/test/test72.cpp b/test/test72.cpp
new file mode 100644
index 0000000..bdc3f3e
--- /dev/null
+++ b/test/test72.cpp
@@ -0,0 +1,165 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test7.hpp"
+
+// Test matrix & vector expression templates
+template<class V, class M, int N>
+struct test_my_matrix_vector {
+    typedef typename V::value_type value_type;
+
+    template<class VP, class MP>
+    void test_with (VP &v1, VP &v2, MP &m1) const {
+        {
+            // Rows and columns
+            initialize_matrix (m1);
+            for (int i = 0; i < N; ++ i) {
+                v1 = ublas::row (m1, i);
+                std::cout << "row (m, " << i << ") = " << v1 << std::endl;
+                v1 = ublas::column (m1, i);
+                std::cout << "column (m, " << i << ") = " << v1 << std::endl;
+            }
+
+            // Outer product
+            initialize_vector (v1);
+            initialize_vector (v2);
+            m1 = ublas::outer_prod (v1, v2);
+            std::cout << "outer_prod (v1, v2) = " << m1 << std::endl;
+
+            // Matrix vector product
+            initialize_matrix (m1);
+            initialize_vector (v1);
+            v2 = ublas::prod (m1, v1);
+            std::cout << "prod (m1, v1) = " << v2 << std::endl;
+            v2 = ublas::prod (v1, m1);
+            std::cout << "prod (v1, m1) = " << v2 << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            V v1 (N), v2 (N);
+            M m1 (N, N);
+            test_with (v1, v2, m1);
+
+            ublas::matrix_row<M> mr1 (m1, 0), mr2 (m1, 1);
+            test_with (mr1, mr2, m1);
+
+            ublas::matrix_column<M> mc1 (m1, 0), mc2 (m1, 1);
+            test_with (mc1, mc2, m1);
+
+#ifdef USE_RANGE
+            ublas::matrix_vector_range<M> mvr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                          mvr2 (m1, ublas::range (0, N), ublas::range (0, N));
+            test_with (mvr1, mvr2, m1);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_vector_slice<M> mvs1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                          mvs2 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (mvs1, mvs2, m1);
+#endif
+        }
+    }
+};
+
+// Test matrix & vector
+void test_matrix_vector () {
+    std::cout << "test_matrix_vector" << std::endl;
+
+#ifdef USE_MATRIX
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::bounded_array<boost::numeric::interval<float>, 3> >,
+                          ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<float>, 3 * 3> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::bounded_array<boost::numeric::interval<double>, 3> >,
+                          ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<double>, 3 * 3> >, 3> () ();
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::unbounded_array<boost::numeric::interval<float> > >,
+                          ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<float> > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::unbounded_array<boost::numeric::interval<double> > >,
+                          ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<double> > >, 3> () ();
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, std::vector<boost::numeric::interval<float> > >,
+                          ublas::matrix<boost::numeric::interval<float>, ublas::row_major, std::vector<boost::numeric::interval<float> > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, std::vector<boost::numeric::interval<double> > >,
+                          ublas::matrix<boost::numeric::interval<double>, ublas::row_major, std::vector<boost::numeric::interval<double> > >, 3> () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_VECTOR_OF_VECTOR
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::bounded_array<boost::numeric::interval<float>, 3> >,
+                          ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<float>, 3>, 3 + 1> >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::bounded_array<boost::numeric::interval<double>, 3> >,
+                          ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<double>, 3>, 3 + 1> >, 3> () ();
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, ublas::unbounded_array<boost::numeric::interval<float> > >,
+                          ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<float> > > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, ublas::unbounded_array<boost::numeric::interval<double> > >,
+                          ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<double> > > >, 3> () ();
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<float>, std::vector<boost::numeric::interval<float> > >,
+                          ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<float> > > >, 3> () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, std::vector" << std::endl;
+    test_my_matrix_vector<ublas::vector<boost::numeric::interval<double>, std::vector<boost::numeric::interval<double> > >,
+                          ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<double> > > >, 3> () ();
+#endif
+#endif
+#endif
+}
diff --git a/test/test73.cpp b/test/test73.cpp
new file mode 100644
index 0000000..e2d68ce
--- /dev/null
+++ b/test/test73.cpp
@@ -0,0 +1,202 @@
+//
+//  Copyright (c) 2000-2002
+//  Joerg Walter, Mathias Koch
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  The authors gratefully acknowledge the support of
+//  GeNeSys mbH & Co. KG in producing this work.
+//
+
+#include "test7.hpp"
+
+// Test matrix expression templates
+template<class M, int N>
+struct test_my_matrix {
+    typedef typename M::value_type value_type;
+
+    template<class MP>
+    void test_with (MP &m1, MP &m2, MP &m3) const {
+        {
+            value_type t;
+
+            // Copy and swap
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m1 = m2;
+            std::cout << "m1 = m2 = " << m1 << std::endl;
+            m1.assign_temporary (m2);
+            std::cout << "m1.assign_temporary (m2) = " << m1 << std::endl;
+            m1.swap (m2);
+            std::cout << "m1.swap (m2) = " << m1 << " " << m2 << std::endl;
+
+            // Zero assignment
+            m1 = ublas::zero_matrix<value_type> (m1.size1 (), m1.size2 ());
+            std::cout << "m1.zero_matrix = " << m1 << std::endl;
+            m1 = m2;
+
+            // Unary matrix operations resulting in a matrix
+            initialize_matrix (m1);
+            m2 = - m1;
+            std::cout << "- m1 = " << m2 << std::endl;
+            m2 = ublas::conj (m1);
+            std::cout << "conj (m1) = " << m2 << std::endl;
+
+            // Binary matrix operations resulting in a matrix
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m3 = m1 + m2;
+            std::cout << "m1 + m2 = " << m3 << std::endl;
+            m3 = m1 - m2;
+            std::cout << "m1 - m2 = " << m3 << std::endl;
+
+            // Scaling a matrix
+            t = N;
+            initialize_matrix (m1);
+            m2 = value_type (1.) * m1;
+            std::cout << "1. * m1 = " << m2 << std::endl;
+            m2 = t * m1;
+            std::cout << "N * m1 = " << m2 << std::endl;
+            initialize_matrix (m1);
+            m2 = m1 * value_type (1.);
+            std::cout << "m1 * 1. = " << m2 << std::endl;
+            m2 = m1 * t;
+            std::cout << "m1 * N = " << m2 << std::endl;
+
+            // Some assignments
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m2 += m1;
+            std::cout << "m2 += m1 = " << m2 << std::endl;
+            m2 -= m1;
+            std::cout << "m2 -= m1 = " << m2 << std::endl;
+            m2 = m2 + m1;
+            std::cout << "m2 = m2 + m1 = " << m2 << std::endl;
+            m2 = m2 - m1;
+            std::cout << "m2 = m1 - m1 = " << m2 << std::endl;
+            m1 *= value_type (1.);
+            std::cout << "m1 *= 1. = " << m1 << std::endl;
+            m1 *= t;
+            std::cout << "m1 *= N = " << m1 << std::endl;
+
+            // Transpose
+            initialize_matrix (m1);
+            m2 = ublas::trans (m1);
+            std::cout << "trans (m1) = " << m2 << std::endl;
+
+            // Hermitean
+            initialize_matrix (m1);
+            m2 = ublas::herm (m1);
+            std::cout << "herm (m1) = " << m2 << std::endl;
+
+            // Matrix multiplication
+            initialize_matrix (m1);
+            initialize_matrix (m2);
+            m3 = ublas::prod (m1, m2);
+            std::cout << "prod (m1, m2) = " << m3 << std::endl;
+        }
+    }
+    void operator () () const {
+        {
+            M m1 (N, N), m2 (N, N), m3 (N, N);
+            test_with (m1, m2, m3);
+
+#ifdef USE_RANGE
+            ublas::matrix_range<M> mr1 (m1, ublas::range (0, N), ublas::range (0, N)),
+                                   mr2 (m2, ublas::range (0, N), ublas::range (0, N)),
+                                   mr3 (m3, ublas::range (0, N), ublas::range (0, N));
+            test_with (mr1, mr2, mr3);
+#endif
+
+#ifdef USE_SLICE
+            ublas::matrix_slice<M> ms1 (m1, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                   ms2 (m2, ublas::slice (0, 1, N), ublas::slice (0, 1, N)),
+                                   ms3 (m3, ublas::slice (0, 1, N), ublas::slice (0, 1, N));
+            test_with (ms1, ms2, ms3);
+#endif
+        }
+    }
+};
+
+// Test matrix
+void test_matrix () {
+    std::cout << "test_matrix" << std::endl;
+
+#ifdef USE_MATRIX
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<float>, 3 * 3> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<boost::numeric::interval<double>, 3 * 3> >, 3 > () ();
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::matrix<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<boost::numeric::interval<double> > >, 3 > () ();
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, std::vector" << std::endl;
+    test_my_matrix<ublas::matrix<boost::numeric::interval<float>, ublas::row_major, std::vector<boost::numeric::interval<float> > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, std::vector" << std::endl;
+    test_my_matrix<ublas::matrix<boost::numeric::interval<double>, ublas::row_major, std::vector<boost::numeric::interval<double> > >, 3 > () ();
+#endif
+#endif
+#endif
+
+#ifdef USE_VECTOR_OF_VECTOR
+#ifdef USE_BOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, bounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<float>, 3>, 3 + 1> >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, bounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::bounded_array<ublas::bounded_array<boost::numeric::interval<double>, 3>, 3 + 1> >, 3 > () ();
+#endif
+#endif
+
+#ifdef USE_UNBOUNDED_ARRAY
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<float> > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, unbounded_array" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, ublas::unbounded_array<ublas::unbounded_array<boost::numeric::interval<double> > > >, 3 > () ();
+#endif
+#endif
+
+#ifdef USE_STD_VECTOR
+#ifdef USE_FLOAT
+    std::cout << "boost::numeric::interval<float>, std::vector" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<float>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<float> > > >, 3 > () ();
+#endif
+
+#ifdef USE_DOUBLE
+    std::cout << "boost::numeric::interval<double>, std::vector" << std::endl;
+    test_my_matrix<ublas::vector_of_vector<boost::numeric::interval<double>, ublas::row_major, std::vector<std::vector<boost::numeric::interval<double> > > >, 3 > () ();
+#endif
+#endif
+#endif
+}
diff --git a/test/test_assignment.cpp b/test/test_assignment.cpp
new file mode 100644
index 0000000..c402ac2
--- /dev/null
+++ b/test/test_assignment.cpp
@@ -0,0 +1,780 @@
+//
+//  Copyright (c) 2010 Athanasios Iliopoulos
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/numeric/ublas/assignment.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/timer.hpp>
+#include <ctime>
+#include "common/testhelper.hpp"
+#include "utils.hpp"
+
+using namespace boost::numeric::ublas;
+
+template <class V>
+bool test_vector() {
+    bool pass = true;
+
+    V a(3), ra(3);
+    a <<=  1, 2, 3;
+    ra(0) = 1; ra(1) = 2; ra(2) = 3;
+    pass &= compare_to(a, ra);
+
+    V b(7), rb(7);
+    b<<= a, 10, a;
+    rb(0) = 1; rb(1) = 2; rb(2) = 3; rb(3)=10, rb(4)= 1; rb(5)=2; rb(6)=3;
+    pass &= compare_to(b, rb);
+
+    {
+    V c(6), rc(6);
+    c <<= 1, move(2), 3 ,4, 5, move(-5), 10, 10;
+    rc(0) = 1; rc(1) = 10; rc(2) = 10; rc(3) = 3; rc(4) = 4; rc(5) = 5;
+    pass &= compare_to(c, rc);
+
+    V d(6), rd(6);
+    d <<= 1, move_to(3), 3 ,4, 5, move_to(1), 10, 10;
+    rd(0) = 1; rd(1) = 10; rd(2) = 10; rd(3) = 3; rd(4) = 4; rd(5) = 5;
+    pass &= compare_to(d, rd);
+    }
+
+    {
+    V c(6), rc(6);
+    c <<= 1, move<2>(), 3 ,4, 5, move<-5>(), 10, 10;
+    rc(0) = 1; rc(1) = 10; rc(2) = 10; rc(3) = 3; rc(4) = 4; rc(5) = 5;
+    pass &= compare_to(c, rc);
+
+    V d(6), rd(6);
+    d <<= 1, move_to<3>(), 3 ,4, 5, move_to<1>(), 10, 10;
+    rd(0) = 1; rd(1) = 10; rd(2) = 10; rd(3) = 3; rd(4) = 4; rd(5) = 5;
+    pass &= compare_to(d, rd);
+    }
+
+
+    {
+    V f(6), rf(6);
+    f <<= 5, 5, 5, 5, 5, 5;
+    V fa(3); fa<<= 1, 2, 3;
+    f <<= fill_policy::index_plus_assign(), fa;
+    rf <<= 6,7,8, 5, 5, 5;
+    pass &= compare_to(f, rf);
+    }
+
+    {
+    V f(6), rf(6);
+    f <<= 5, 5, 5, 5, 5, 5;
+    V fa(3); fa<<= 1, 2, 3;
+    f <<= fill_policy::index_minus_assign(), fa;
+    rf <<= 4,3,2, 5, 5, 5;
+    pass &= compare_to(f, rf);
+    }
+
+    return pass;
+}
+
+template <class V>
+bool test_vector_sparse_push_back() {
+    bool pass = true;
+
+    V a(3), ra(3);
+    a <<= fill_policy::sparse_push_back(), 1, 2, 3;
+    ra(0) = 1; ra(1) = 2; ra(2) = 3;
+    pass &= compare_to(a, ra);
+
+    V b(7), rb(7);
+    b<<= fill_policy::sparse_push_back(), a, 10, a;
+    rb(0) = 1; rb(1) = 2; rb(2) = 3; rb(3)=10, rb(4)= 1; rb(5)=2; rb(6)=3;
+    pass &= compare_to(b, rb);
+
+    V c(6), rc(6);
+    c <<= fill_policy::sparse_push_back(), 1, move(2), 3 ,4, 5; // Move back (i.e. negative is dangerous for push_back)
+    rc(0) = 1; rc(1) = 0; rc(2) = 0; rc(3) = 3; rc(4) = 4; rc(5) = 5;
+    pass &= compare_to(c, rc);
+
+    V d(6), rd(6);
+    d <<= fill_policy::sparse_push_back(), 1, move_to(3), 3 ,4, 5; // Move back (i.e. before current index is dangerous for push_back)
+    rd(0) = 1; rd(1) = 0; rd(2) = 0; rd(3) = 3; rd(4) = 4; rd(5) = 5;
+    pass &= compare_to(d, rd);
+
+    V e(6), re(6);
+    e <<= fill_policy::sparse_push_back(), 1, move_to(3), 3 ,4, 5, fill_policy::sparse_insert(), move_to(1), 10, 10; // If you want to move back, use this
+    re(0) = 1; re(1) = 10; re(2) = 10; re(3) = 3; re(4) = 4; re(5) = 5;
+    pass &= compare_to(e, re);
+
+    return pass;
+}
+
+
+template <class V>
+bool test_vector_sparse_insert() {
+    bool pass = true;
+
+    V a(3), ra(3);
+    a <<= fill_policy::sparse_insert(), 1, 2, 3;
+    ra(0) = 1; ra(1) = 2; ra(2) = 3;
+    pass &= compare_to(a, ra);
+
+    V b(7), rb(7);
+    b<<= fill_policy::sparse_insert(), a, 10, a;
+    rb(0) = 1; rb(1) = 2; rb(2) = 3; rb(3)=10, rb(4)= 1; rb(5)=2; rb(6)=3;
+    pass &= compare_to(b, rb);
+
+    V c(6), rc(6);
+    c <<= fill_policy::sparse_insert(), 1, move(2), 3 ,4, 5, move(-5), 10, 10; // Move back (i.e. negative is dangerous for sparse)
+    rc(0) = 1; rc(1) = 10; rc(2) = 10; rc(3) = 3; rc(4) = 4; rc(5) = 5;
+    pass &= compare_to(c, rc);
+
+
+    V d(6), rd(6);
+    d <<= fill_policy::sparse_insert(), 1, move_to(3), 3 ,4, 5, move_to(1), 10, 10; // Move back (i.e.before is dangerous for sparse)
+    rd(0) = 1; rd(1) = 10; rd(2) = 10; rd(3) = 3; rd(4) = 4; rd(5) = 5;
+    pass &= compare_to(d, rd);
+
+
+    return pass;
+}
+
+
+template <class V>
+bool test_matrix() {
+    bool pass = true;
+
+    V A(3,3), RA(3,3);
+    A <<= 1, 2, 3, 4, 5, 6, 7, 8, 9;
+    RA(0,0)= 1; RA(0,1)=2; RA(0,2)=3;
+    RA(1,0)= 4; RA(1,1)=5; RA(1,2)=6;
+    RA(2,0)= 7; RA(2,1)=8; RA(2,2)=9;
+    pass &= compare_to(A, RA);
+
+    {
+    V B(3,3), RB(3,3);
+    vector<typename V::value_type>  b(3);
+    b<<= 4,5,6;
+    B<<= 1, 2, 3, b, 7, project(b, range(1,3));
+    RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; // If the first worked we can now probably use it.
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(3,3), RB(3,3);
+    vector<typename V::value_type>  b(3);
+    b<<= 4,5,6;
+    B<<= move(1,0), b, move_to(0,0), 1, 2, 3, move(1,0), 7, project(b, range(1,3));
+    RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(3,3), RB(3,3);
+    vector<typename V::value_type>  b(9);
+    b<<= 1, 2, 3, 4, 5, 6, 7, 8, 9;
+    B<<=b;
+    RB<<=1, 2, 3, 4, 5, 6, 7, 8, 9;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    V C(2,2);
+    C <<=    2, 3,
+            4, 5;
+    B<<= C,C,
+        C,C;
+    RB <<=   2,3,2,3,
+            4,5,4,5,
+            2,3,2,3,
+            4,5,4,5;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    V C(2,2);
+    C <<= 2, 3, 4, 5;
+    B<<= C, zero_matrix<typename V::value_type>(2,2),
+        zero_matrix<typename V::value_type>(2,2), C;
+    RB<<=    2,3,0,0,
+            4,5,0,0,
+            0,0,2,3,
+            0,0,4,5;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    V C(2,2);
+    C <<= 2, 3, 4, 5;
+    B<<= C, zero_matrix<typename V::value_type>(2,2),
+        zero_matrix<typename V::value_type>(2,2), C;
+    RB<<=    2,3,0,0,
+            4,5,0,0,
+            0,0,2,3,
+            0,0,4,5;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4); // We need that because of the non-zero instatiation of dense types.
+    V C(2,2);
+    C <<= 2, 3, 4, 5;
+    B<<= move(1,1), C;
+    RB<<=    0,0,0,0,
+            0,2,3,0,
+            0,4,5,0,
+            0,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<= move_to(0,1), 2, 3, next_row(), 1, 2, next_row(), 4, 5;
+    RB<<=    0,2,3,0,
+            1,2,0,0,
+            4,5,0,0,
+            0,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, 6, next_column(), 4, 5;
+    RB<<=    0,2,4,0,
+            0,3,5,0,
+            0,6,0,0,
+            0,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, next_row(), traverse_policy::by_row(), 4, 5;
+    RB<<=    0,2,0,0,
+            0,3,0,0,
+            0,0,0,0,
+            4,5,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8;
+    RB<<=    0,2,0,0,
+            0,3,0,0,
+            4,5,6,7,
+            8,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8,9, begin1(), 1, 2;
+    RB<<=    0,2,1,2,
+            0,3,0,0,
+            4,5,6,7,
+            8,9,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = scalar_matrix<typename V::value_type>(4,4,1);
+    V C(2,2);
+    C <<= 1, 2, 3, 4;
+    B<<= fill_policy::index_plus_assign(), move(1,1), C;
+    RB<<=    1,1,1,1,
+            1,2,3,1,
+            1,4,5,1,
+            1,1,1,1;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = scalar_matrix<typename V::value_type>(4,4,5);
+    V C(2,2);
+    C <<= 1, 2, 3, 4;
+    B<<= fill_policy::index_minus_assign(), move(1,1), C;
+    RB<<=    5,5,5,5,
+            5,4,3,5,
+            5,2,1,5,
+            5,5,5,5;
+    pass &= compare_to(B, RB);
+    }
+
+
+    return pass;
+}
+
+template <class V>
+bool test_matrix_sparse_push_back() {
+    bool pass = true;
+
+    V A(3,3), RA(3,3);
+    A <<= fill_policy::sparse_push_back(), 1, 2, 3, 4, 5, 6, 7, 8, 9;
+    RA(0,0)= 1; RA(0,1)=2; RA(0,2)=3;
+    RA(1,0)= 4; RA(1,1)=5; RA(1,2)=6;
+    RA(2,0)= 7; RA(2,1)=8; RA(2,2)=9;
+    pass &= compare_to(A, RA);
+
+    {
+    V B(3,3), RB(3,3);
+    vector<typename V::value_type>  b(3);
+    b<<= 4,5,6;
+    B<<=fill_policy::sparse_push_back(), 1, 2, 3, b, 7, project(b, range(1,3));
+    RB<<= 1, 2, 3, 4, 5, 6, 7, 5, 6; // If the first worked we can now probably use it.
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(3,3), RB(3,3);
+    vector<typename V::value_type>  b(3);
+    b<<= 4,5,6;
+    B<<=fill_policy::sparse_push_back(), move(1,0), b, fill_policy::sparse_insert(), move_to(0,0), 1, 2, 3, move(1,0), 7, project(b, range(1,3));
+    RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(3,3), RB(3,3);
+    vector<typename V::value_type>  b(9);
+    b<<= 1, 2, 3, 4, 5, 6, 7, 8, 9;
+    B<<=b;
+    RB<<=1, 2, 3, 4, 5, 6, 7, 8, 9;
+    pass &= compare_to(B, RB);
+    }
+
+
+    {
+    V B(4,4), RB(4,4);
+    V C(2,2);
+    C <<=    2, 3,
+            4, 5;
+    // It might get complicated for sparse push_back, this must go into the tutorial. (This way is not convient nor fast)
+    B<<=fill_policy::sparse_push_back(), C, move_to(2,2), C, fill_policy::sparse_insert(), move_to(0,2), C, C;
+    RB <<=   2,3,2,3,
+            4,5,4,5,
+            2,3,2,3,
+            4,5,4,5;
+    pass &= compare_to(B, RB);
+    }
+
+
+    {
+    V B(4,4), RB(4,4);
+    V C(2,2);
+    C <<= 2, 3, 4, 5;
+    B<<=fill_policy::sparse_push_back(), C, move_to(2,2), C;
+    RB<<=    2,3,0,0,
+            4,5,0,0,
+            0,0,2,3,
+            0,0,4,5;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    V C(2,2);
+    C <<= 2, 3, 4, 5;
+    B<<=fill_policy::sparse_push_back(), move(1,1), C;
+    RB<<=    0,0,0,0,
+            0,2,3,0,
+            0,4,5,0,
+            0,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=fill_policy::sparse_push_back(), move_to(0,1), 2, 3, next_row(), 1, 2, next_row(), 4, 5;
+    RB<<=    0,2,3,0,
+            1,2,0,0,
+            4,5,0,0,
+            0,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+    // The next will not work with sparse push_back because elements that are prior to the ones already in are attempted to be added
+/*
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, 6, next_column(), 4, 5;
+    RB<<=    0,2,4,0,
+            0,3,5,0,
+            0,6,0,0,
+            0,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+*/
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, next_row(), traverse_policy::by_row(), 4, 5;
+    RB<<=    0,2,0,0,
+            0,3,0,0,
+            0,0,0,0,
+            4,5,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8;
+    RB<<=    0,2,0,0,
+            0,3,0,0,
+            4,5,6,7,
+            8,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    // The next will not work with sparse push_back because elements that are prior to the ones already in are attempted to be added
+/*
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=fill_policy::sparse_push_back(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8,9, begin1(), 1, 2;
+    RB<<=    0,2,1,2,
+            0,3,0,0,
+            4,5,6,7,
+            8,9,0,0;
+    pass &= compare_to(B, RB);
+    }
+*/
+    return pass;
+}
+
+template <class V>
+bool test_matrix_sparse_insert() {
+    bool pass = true;
+
+    V A(3,3), RA(3,3);
+    A <<= fill_policy::sparse_insert(), 1, 2, 3, 4, 5, 6, 7, 8, 9;
+    RA(0,0)= 1; RA(0,1)=2; RA(0,2)=3;
+    RA(1,0)= 4; RA(1,1)=5; RA(1,2)=6;
+    RA(2,0)= 7; RA(2,1)=8; RA(2,2)=9;
+    pass &= compare_to(A, RA);
+
+    {
+    V B(3,3), RB(3,3);
+    vector<typename V::value_type>  b(3);
+    b<<= 4,5,6;
+    B<<=fill_policy::sparse_insert(), 1, 2, 3, b, 7, project(b, range(1,3));
+    RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6; // If the first worked we can now probably use it.
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(3,3), RB(3,3);
+    vector<typename V::value_type>  b(3);
+    b<<= 4,5,6;
+    B<<=fill_policy::sparse_insert(), move(1,0), b, fill_policy::sparse_insert(), move_to(0,0), 1, 2, 3, move(1,0), 7, project(b, range(1,3));
+    RB<<=1, 2, 3, 4, 5, 6, 7, 5, 6;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(3,3), RB(3,3);
+    vector<typename V::value_type>  b(9);
+    b<<= 1, 2, 3, 4, 5, 6, 7, 8, 9;
+    B<<=b;
+    RB<<=1, 2, 3, 4, 5, 6, 7, 8, 9;
+    pass &= compare_to(B, RB);
+    }
+
+
+    {
+    V B(4,4), RB(4,4);
+    V C(2,2);
+    C <<=    2, 3,
+            4, 5;
+    B<<=fill_policy::sparse_insert(), C, C, C, C;
+    RB <<=   2,3,2,3,
+            4,5,4,5,
+            2,3,2,3,
+            4,5,4,5;
+    pass &= compare_to(B, RB);
+    }
+
+
+    {
+    V B(4,4), RB(4,4);
+    V C(2,2);
+    C <<= 2, 3, 4, 5;
+    B<<=fill_policy::sparse_insert(), C, move_to(2,2), C;
+    RB<<=    2,3,0,0,
+            4,5,0,0,
+            0,0,2,3,
+            0,0,4,5;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    V C(2,2);
+    C <<= 2, 3, 4, 5;
+    B<<=fill_policy::sparse_insert(), move(1,1), C;
+    RB<<=    0,0,0,0,
+            0,2,3,0,
+            0,4,5,0,
+            0,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=fill_policy::sparse_insert(), move_to(0,1), 2, 3, next_row(), 1, 2, next_row(), 4, 5;
+    RB<<=    0,2,3,0,
+            1,2,0,0,
+            4,5,0,0,
+            0,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, 6, next_column(), 4, 5;
+    RB<<=    0,2,4,0,
+            0,3,5,0,
+            0,6,0,0,
+            0,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, next_row(), traverse_policy::by_row(), 4, 5;
+    RB<<=    0,2,0,0,
+            0,3,0,0,
+            0,0,0,0,
+            4,5,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8;
+    RB<<=    0,2,0,0,
+            0,3,0,0,
+            4,5,6,7,
+            8,0,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    {
+    V B(4,4), RB(4,4);
+    B = zero_matrix<typename V::value_type>(4,4);
+    B<<=fill_policy::sparse_insert(),traverse_policy::by_column(), move_to(0,1), 2, 3, begin2(), traverse_policy::by_row(), 4, 5, 6, 7, 8,9, begin1(), 1, 2;
+    RB<<=    0,2,1,2,
+            0,3,0,0,
+            4,5,6,7,
+            8,9,0,0;
+    pass &= compare_to(B, RB);
+    }
+
+    return pass;
+}
+
+
+BOOST_UBLAS_TEST_DEF (test_vector) {
+
+    BOOST_UBLAS_DEBUG_TRACE( "Starting operator \"<<= \" vector assignment tests" );
+
+    BOOST_UBLAS_TEST_CHECK(test_vector<vector<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<vector<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<vector<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<vector<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<vector<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<vector<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<vector<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<vector<char> >());
+
+    BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<double,7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<float,7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<long,7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<unsigned long,7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<int,7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<unsigned int,7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<std::size_t,7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_vector<bounded_vector<char,7> >()));
+
+    BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<unsigned int> >())
+    BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<std::size_t> >())
+    BOOST_UBLAS_TEST_CHECK(test_vector<mapped_vector<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<compressed_vector<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<long> >())
+    BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<unsigned long> >())
+    BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector<coordinate_vector<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<compressed_vector<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_push_back<coordinate_vector<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<compressed_vector<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_vector_sparse_insert<coordinate_vector<char> >());
+}
+
+BOOST_UBLAS_TEST_DEF (test_matrix) {
+
+    BOOST_UBLAS_DEBUG_TRACE( "Starting operator \"<<= \" matrix assignment tests" );
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<matrix<char> >());
+
+    BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<double,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<float,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<long,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<unsigned long,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<int,7,7 > >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<unsigned int,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<char,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix<bounded_matrix<std::size_t,7, 7> >()));
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<unsigned int> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<std::size_t> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix<mapped_matrix<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<compressed_matrix<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<long> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<unsigned long> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix<coordinate_matrix<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<compressed_matrix<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_push_back<coordinate_matrix<char> >());
+
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<compressed_matrix<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_sparse_insert<coordinate_matrix<char> >());
+}
+
+
+int main () {
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_vector );
+    BOOST_UBLAS_TEST_DO( test_matrix );
+
+    BOOST_UBLAS_TEST_END();
+
+    return EXIT_SUCCESS;
+}
diff --git a/test/test_banded_storage_layout.cpp b/test/test_banded_storage_layout.cpp
new file mode 100644
index 0000000..6b4e68a
--- /dev/null
+++ b/test/test_banded_storage_layout.cpp
@@ -0,0 +1,291 @@
+
+#include <iostream>
+#include <boost/numeric/ublas/banded.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/numeric/ublas/operation.hpp>
+#include <iomanip>
+
+#include "utils.hpp"
+
+using namespace boost::numeric::ublas;
+
+int expected_index( int index, column_major ) {
+   // this is the data shown on http://www.netlib.org/lapack/lug/node124.html
+   // read column-by-column, aka column_major
+   int mapping[] = { 0, 11, 21, 31, 12, 22, 32, 42, 23, 33, 43, 53, 34, 44, 54, 0, 45, 55, 0, 0 };
+   return mapping[ index ];
+}
+
+
+int expected_index( int index, row_major ) {
+   // this is the data shown on http://www.netlib.org/lapack/lug/node124.html
+   // read row-by-row, aka row_major
+   int mapping[] = { 0, 0, 11, 12, 0, 21, 22, 23, 31, 32, 33, 34, 42, 43, 44, 45, 53, 54, 55, 0 };
+   return mapping[ index ];
+}
+
+int expected_index_6_by_5( int index, column_major ) {
+   // read column-by-column, aka column_major
+   int mapping[] = { 0, 11, 21, 31, 12, 22, 32, 42, 23, 33, 43, 53, 34, 44, 54, 64, 45, 55, 65, 0 };
+   return mapping[ index ];
+}
+
+int expected_index_6_by_5( int index, row_major ) {
+   // read row-by-row, aka row_major
+   int mapping[] = { 0, 0, 11, 12, 0, 21, 22, 23, 31, 32, 33, 34, 42, 43, 44, 45, 53, 54, 55, 0, 64, 65, 0, 0 };
+   return mapping[ index ];
+}
+
+int expected_index_5_by_6( int index, column_major ) {
+   // read column-by-column, aka column_major
+   int mapping[] = { 0, 11, 21, 31, 12, 22, 32, 42, 23, 33, 43, 53, 34, 44, 54, 0, 45, 55, 0, 0, 56, 0, 0, 0 };
+   return mapping[ index ];
+}
+
+int expected_index_5_by_6( int index, row_major ) {
+   // read row-by-row, aka row_major
+   int mapping[] = { 0, 0, 11, 12, 0, 21, 22, 23, 31, 32, 33, 34, 42, 43, 44, 45, 53, 54, 55, 56};
+   return mapping[ index ];
+}
+
+template< typename Orientation >
+bool test_band_storage() {
+        
+    int m = 5;
+    int n = 5;
+    int kl = 2;
+    int ku = 1;
+    
+    banded_matrix< int, Orientation > test_matrix( m, n, kl, ku );
+    test_matrix.clear();
+    int band_storage_size = test_matrix.data().size();
+    
+    test_matrix( 0, 0 ) = 11;
+    test_matrix( 0, 1 ) = 12;
+    test_matrix( 1, 0 ) = 21;
+    test_matrix( 1, 1 ) = 22;
+    test_matrix( 1, 2 ) = 23;
+    test_matrix( 2, 0 ) = 31;
+    test_matrix( 2, 1 ) = 32;
+    test_matrix( 2, 2 ) = 33;
+    test_matrix( 2, 3 ) = 34;
+    test_matrix( 3, 1 ) = 42;
+    test_matrix( 3, 2 ) = 43;
+    test_matrix( 3, 3 ) = 44;
+    test_matrix( 3, 4 ) = 45;
+    test_matrix( 4, 2 ) = 53;
+    test_matrix( 4, 3 ) = 54;
+    test_matrix( 4, 4 ) = 55;
+        
+    BOOST_UBLAS_TEST_TRACE( "Full matrix" );
+    BOOST_UBLAS_TEST_TRACE( std::setw( 3 ) << test_matrix );
+    
+    BOOST_UBLAS_TEST_TRACE( "data() of matrix" );
+    for ( int i = 0; i < band_storage_size; ++i ) {
+        std::cerr << test_matrix.data()[ i ] << " ";
+    }
+    std::cerr << std::endl;
+   
+    BOOST_UBLAS_TEST_TRACE( "Expected data() of matrix" );
+    for ( int i = 0; i < band_storage_size; ++i ) {
+        std::cerr << expected_index( i, Orientation() ) << " ";
+    }
+    std::cerr << std::endl;
+    
+    size_t mismatch = 0;
+
+    for ( int i = 0; i < band_storage_size; ++i ) {
+      if ( test_matrix.data()[ i ] != expected_index( i, Orientation() ) ) {
+        ++mismatch;
+      }
+    }
+
+    return 0 == mismatch;
+}
+
+template< typename Orientation >
+bool test_band_storage_6_by_5() {
+
+    int m = 6;
+    int n = 5;
+    int kl = 2;
+    int ku = 1;
+
+
+    banded_matrix< int, Orientation > test_matrix( m, n, kl, ku );
+    test_matrix.clear();
+    int band_storage_size = test_matrix.data().size();
+
+    test_matrix( 0, 0 ) = 11;
+    test_matrix( 0, 1 ) = 12;
+    test_matrix( 1, 0 ) = 21;
+    test_matrix( 1, 1 ) = 22;
+    test_matrix( 1, 2 ) = 23;
+    test_matrix( 2, 0 ) = 31;
+    test_matrix( 2, 1 ) = 32;
+    test_matrix( 2, 2 ) = 33;
+    test_matrix( 2, 3 ) = 34;
+    test_matrix( 3, 1 ) = 42;
+    test_matrix( 3, 2 ) = 43;
+    test_matrix( 3, 3 ) = 44;
+    test_matrix( 3, 4 ) = 45;
+    test_matrix( 4, 2 ) = 53;
+    test_matrix( 4, 3 ) = 54;
+    test_matrix( 4, 4 ) = 55;
+    test_matrix( 5, 3 ) = 64;
+    test_matrix( 5, 4 ) = 65;
+
+    BOOST_UBLAS_TEST_TRACE( "Full matrix" );
+    BOOST_UBLAS_TEST_TRACE( std::setw( 3 ) << test_matrix );
+
+    BOOST_UBLAS_TEST_TRACE( "data() of matrix" );
+    for ( int i = 0; i < band_storage_size; ++i ) {
+        std::cerr << test_matrix.data()[ i ] << " ";
+    }
+    std::cerr << std::endl;
+
+    BOOST_UBLAS_TEST_TRACE( "Expected data() of matrix" );
+    for ( int i = 0; i < band_storage_size; ++i ) {
+        std::cerr << expected_index_6_by_5( i, Orientation() ) << " ";
+    }
+    std::cerr << std::endl;
+
+    size_t mismatch = 0;
+
+    for ( int i = 0; i < band_storage_size; ++i ) {
+      if ( test_matrix.data()[ i ] != expected_index_6_by_5( i, Orientation() ) ) {
+        ++mismatch;
+      }
+    }
+
+    return 0 == mismatch;
+}
+
+template< typename Orientation >
+bool test_band_storage_5_by_6() {
+
+    int m = 5;
+    int n = 6;
+    int kl = 2;
+    int ku = 1;
+
+    banded_matrix< int, Orientation > test_matrix( m, n, kl, ku );
+    test_matrix.clear();
+    int band_storage_size = test_matrix.data().size();
+
+    test_matrix( 0, 0 ) = 11;
+    test_matrix( 0, 1 ) = 12;
+    test_matrix( 1, 0 ) = 21;
+    test_matrix( 1, 1 ) = 22;
+    test_matrix( 1, 2 ) = 23;
+    test_matrix( 2, 0 ) = 31;
+    test_matrix( 2, 1 ) = 32;
+    test_matrix( 2, 2 ) = 33;
+    test_matrix( 2, 3 ) = 34;
+    test_matrix( 3, 1 ) = 42;
+    test_matrix( 3, 2 ) = 43;
+    test_matrix( 3, 3 ) = 44;
+    test_matrix( 3, 4 ) = 45;
+    test_matrix( 4, 2 ) = 53;
+    test_matrix( 4, 3 ) = 54;
+    test_matrix( 4, 4 ) = 55;
+    test_matrix( 4, 5 ) = 56;
+
+    BOOST_UBLAS_TEST_TRACE( "Full matrix" );
+    BOOST_UBLAS_TEST_TRACE( std::setw( 3 ) << test_matrix );
+
+    BOOST_UBLAS_TEST_TRACE( "data() of matrix" );
+    for ( int i = 0; i < band_storage_size; ++i ) {
+        std::cerr << test_matrix.data()[ i ] << " ";
+    }
+    std::cerr << std::endl;
+
+    BOOST_UBLAS_TEST_TRACE( "Expected data() of matrix" );
+    for ( int i = 0; i < band_storage_size; ++i ) {
+        std::cerr << expected_index_5_by_6( i, Orientation() ) << " ";
+    }
+    std::cerr << std::endl;
+
+    size_t mismatch = 0;
+
+    for ( int i = 0; i < band_storage_size; ++i ) {
+      if ( test_matrix.data()[ i ] != expected_index_5_by_6( i, Orientation() ) ) {
+        ++mismatch;
+      }
+    }
+
+    return 0 == mismatch;
+}
+
+
+
+
+BOOST_UBLAS_TEST_DEF( banded_matrix_column_major )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < column_major >" );
+
+    BOOST_UBLAS_TEST_CHECK( test_band_storage< column_major >() );
+}
+
+BOOST_UBLAS_TEST_DEF( banded_matrix_row_major )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < row_major >" );
+
+    BOOST_UBLAS_TEST_CHECK( test_band_storage< row_major >() );
+}
+
+BOOST_UBLAS_TEST_DEF( banded_matrix_column_major_6_by_5 )
+{
+    BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < column_major > 6x5" );
+
+    BOOST_UBLAS_TEST_CHECK( test_band_storage_6_by_5< column_major >() );
+}
+
+BOOST_UBLAS_TEST_DEF( banded_matrix_row_major_6_by_5 )
+{
+    BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < row_major > 6x5" );
+
+    BOOST_UBLAS_TEST_CHECK( test_band_storage_6_by_5< row_major >() );
+}
+
+BOOST_UBLAS_TEST_DEF( banded_matrix_column_major_5_by_6 )
+{
+    BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < column_major > 5x6" );
+
+    BOOST_UBLAS_TEST_CHECK( test_band_storage_5_by_6< column_major >() );
+}
+
+BOOST_UBLAS_TEST_DEF( banded_matrix_row_major_5_by_6 )
+{
+    BOOST_UBLAS_TEST_TRACE( "Test case: storage layout banded_matrix < row_major > 5x6" );
+
+    BOOST_UBLAS_TEST_CHECK( test_band_storage_5_by_6< row_major >() );
+}
+
+int main()
+{
+
+	BOOST_UBLAS_TEST_SUITE( "Test storage layout of banded matrix type" );
+
+	BOOST_UBLAS_TEST_TRACE( "Example data taken from http://www.netlib.org/lapack/lug/node124.html" );
+
+	BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( banded_matrix_column_major );
+    
+    BOOST_UBLAS_TEST_DO( banded_matrix_row_major );
+
+    BOOST_UBLAS_TEST_DO( banded_matrix_column_major_6_by_5 );
+
+    BOOST_UBLAS_TEST_DO( banded_matrix_row_major_6_by_5 );
+
+    BOOST_UBLAS_TEST_DO( banded_matrix_column_major_5_by_6 );
+
+    BOOST_UBLAS_TEST_DO( banded_matrix_row_major_5_by_6 );
+
+	BOOST_UBLAS_TEST_END();
+
+    return EXIT_SUCCESS;
+}
+
+
diff --git a/test/test_complex_norms.cpp b/test/test_complex_norms.cpp
new file mode 100644
index 0000000..e923d70
--- /dev/null
+++ b/test/test_complex_norms.cpp
@@ -0,0 +1,82 @@
+// Copyright 2010 Gunter Winkler <guwi17@gmx.de>
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <complex>
+
+#include "utils.hpp"
+
+using namespace boost::numeric::ublas;
+
+static const double TOL(1.0e-5); ///< Used for comparing two real numbers.
+
+BOOST_UBLAS_TEST_DEF ( test_double_complex_norm_inf ) {
+    typedef std::complex<double> dComplex;
+    vector<dComplex> v(4);
+    for (unsigned int i = 0; i < v.size(); ++i)
+        v[i] = dComplex(i, i + 1);
+
+    const double expected = abs(v[3]);
+
+    BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_inf(v) );
+    BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - expected) < TOL);
+    v *= 3.;
+    BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - (3.0*expected)) < TOL);
+}
+
+BOOST_UBLAS_TEST_DEF ( test_double_complex_norm_2 ) {
+    typedef std::complex<double> dComplex;
+    vector<dComplex> v(4);
+    for (unsigned int i = 0; i < v.size(); ++i)
+        v[i] = dComplex(i, i + 1);
+
+    const double expected = sqrt(44.0);
+
+    BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_2(v) );
+    BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - expected) < TOL);
+    v *= 3.;
+    BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - (3.0*expected)) < TOL);
+}
+
+BOOST_UBLAS_TEST_DEF ( test_float_complex_norm_inf ) {
+    typedef std::complex<float> dComplex;
+    vector<dComplex> v(4);
+    for (unsigned int i = 0; i < v.size(); ++i)
+        v[i] = dComplex(i, i + 1);
+
+    const float expected = abs(v[3]);
+
+    BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_inf(v) );
+    BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - expected) < TOL);
+    v *= 3.;
+    BOOST_UBLAS_TEST_CHECK(std::abs(norm_inf(v) - (3.0*expected)) < TOL);
+}
+
+BOOST_UBLAS_TEST_DEF ( test_float_complex_norm_2 ) {
+    typedef std::complex<float> dComplex;
+    vector<dComplex> v(4);
+    for (unsigned int i = 0; i < v.size(); ++i)
+        v[i] = dComplex(i, i + 1);
+
+    const double expected = sqrt(44.0);
+
+    BOOST_UBLAS_DEBUG_TRACE( "norm is " << norm_2(v) );
+    BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - expected) < TOL);
+    v *= 3.;
+    BOOST_UBLAS_TEST_CHECK(std::abs(norm_2(v) - (3.0*expected)) < TOL);
+}
+
+int main() {
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_double_complex_norm_inf );
+    BOOST_UBLAS_TEST_DO( test_float_complex_norm_inf );
+    BOOST_UBLAS_TEST_DO( test_double_complex_norm_2 );
+    BOOST_UBLAS_TEST_DO( test_float_complex_norm_2 );
+
+    BOOST_UBLAS_TEST_END();
+}
diff --git a/test/test_coordinate_matrix_inplace_merge.cpp b/test/test_coordinate_matrix_inplace_merge.cpp
new file mode 100644
index 0000000..75d1f70
--- /dev/null
+++ b/test/test_coordinate_matrix_inplace_merge.cpp
@@ -0,0 +1,120 @@
+//  Copyright (c) 2011 David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
+# define BOOST_UBLAS_NO_ELEMENT_PROXIES
+#endif
+
+#include <boost/numeric/ublas/assignment.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/matrix_expression.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include "common/testhelper.hpp"
+#include "utils.hpp"
+
+using std::cout;
+using std::endl;
+
+const double TOL = 1e-15;
+
+template<typename T>
+bool check_sortedness(const boost::numeric::ublas::coordinate_matrix<T>& matrix) {
+  bool result = true;
+  typedef boost::numeric::ublas::coordinate_matrix<T> matrix_type;
+  typename matrix_type::index_array_type i1 = matrix.index1_data();
+  typename matrix_type::index_array_type i2 = matrix.index2_data();
+  typename matrix_type::array_size_type size = matrix.filled();
+
+  for (typename matrix_type::array_size_type i = 0; i + 1 < size && result; ++ i) {
+    result &= ( (i1[i] < i1[i + 1]) ||
+                ((i1[i] == i1[i]) &&
+                 (i2[i] < i2[i + 1])) );
+
+  }
+  return result;
+}
+
+void print_entries(size_t size_x, size_t size_y,
+                   const std::vector<std::pair<size_t, size_t> >& entries)
+{
+  std::cerr << "Error - Size:" << size_x << " x " << size_y << ". Entries: ";
+  for (size_t i = 0; i < entries.size(); ++ i) {
+    std::cerr << entries[i].first << ", " << entries[i].second << "; ";
+  }
+  std::cerr << "\n";
+}
+
+
+BOOST_UBLAS_TEST_DEF( test_coordinate_matrix_inplace_merge_random )
+{
+  const size_t max_repeats = 100;
+  const size_t max_size = 100;
+  const size_t dim_var = 10;
+  const size_t nr_entries = 10;
+
+  for (size_t repeats = 1; repeats < max_repeats; ++repeats ) {
+    for (size_t size = 1; size < max_size; size += 5) {
+      size_t size_x = size + rand() % dim_var;
+      size_t size_y = size + rand() % dim_var;
+
+      boost::numeric::ublas::coordinate_matrix<double> matrix_coord(size_x, size_y);
+      boost::numeric::ublas::matrix<double> matrix_dense(size_x, size_y, 0);
+
+      matrix_coord.sort();
+
+      std::vector<std::pair<size_t, size_t> > entries;
+      for (size_t entry = 0; entry < nr_entries; ++ entry) {
+        int x = rand() % size_x;
+        int y = rand() % size_y;
+        entries.push_back(std::make_pair(x, y));
+        matrix_coord.append_element(x, y, 1);
+        matrix_dense(x, y) += 1;
+      }
+      matrix_coord.sort();
+
+      {
+        bool sorted = check_sortedness(matrix_coord);
+        bool identical = compare_to(matrix_coord, matrix_dense, TOL);
+        if (!(sorted && identical)) {
+          print_entries(size_x, size_y, entries);
+        }
+        BOOST_UBLAS_TEST_CHECK( check_sortedness(matrix_coord) );
+        BOOST_UBLAS_TEST_CHECK( compare_to(matrix_coord, matrix_dense, TOL) );
+      }
+
+      for (size_t entry = 0; entry < nr_entries; ++ entry) {
+        int x = rand() % size_x;
+        int y = rand() % size_y;
+        entries.push_back(std::make_pair(x, y));
+        matrix_coord(x, y) += 1;
+        matrix_dense(x, y) += 1;
+        matrix_coord.sort();
+      }
+
+      {
+        bool sorted = check_sortedness(matrix_coord);
+        bool identical = compare_to(matrix_coord, matrix_dense, TOL);
+        if (!(sorted && identical)) {
+          print_entries(size_x, size_y, entries);
+        }
+        BOOST_UBLAS_TEST_CHECK( sorted );
+        BOOST_UBLAS_TEST_CHECK( identical );
+      }
+    }
+  }
+}
+
+int main()
+{
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_coordinate_matrix_inplace_merge_random );
+
+    BOOST_UBLAS_TEST_END();
+
+    return EXIT_SUCCESS;;
+}
diff --git a/test/test_coordinate_matrix_sort.cpp b/test/test_coordinate_matrix_sort.cpp
new file mode 100644
index 0000000..d07abb3
--- /dev/null
+++ b/test/test_coordinate_matrix_sort.cpp
@@ -0,0 +1,73 @@
+//  Copyright (c) 2011 David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
+# define BOOST_UBLAS_NO_ELEMENT_PROXIES
+#endif
+
+#include<boost/numeric/ublas/matrix_sparse.hpp>
+#include<boost/numeric/ublas/io.hpp>
+
+#include "utils.hpp"
+
+using std::cout;
+using std::endl;
+
+BOOST_UBLAS_TEST_DEF( test_coordinate_matrix_sort )
+{
+
+    boost::numeric::ublas::coordinate_matrix<double> matrix_mask(3, 3, 2);
+    cout << "Setting matrix(1,1) = 2.1" << endl;
+    matrix_mask(1,1) = 2.1;
+
+    cout << "Displaying matrix(1,1)" << endl;
+    std::cout << matrix_mask(1,1) << std::endl;
+
+    BOOST_UBLAS_DEBUG_TRACE( "Displaying matrix(1,1)" << matrix_mask(1,1) );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask(1,1) == 2.1 );
+
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[0] == 1 );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[0] == 1 );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[0] == 2.1 );
+
+    BOOST_UBLAS_DEBUG_TRACE( "Setting matrix(0,1) = 1.1" );
+    matrix_mask(0, 1) = 1.1;
+
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[0] == 1 );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[0] == 1 );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[0] == 2.1 );
+
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[1] == 0 );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[1] == 1 );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[1] == 1.1 );
+
+    BOOST_UBLAS_DEBUG_TRACE( "Sort the matrix - this would be triggered by any element lookup." );
+    matrix_mask.sort();
+
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[1] == 1 );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[1] == 1 );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[1] == 2.1 );
+
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.index1_data()[0] == 0 );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.index2_data()[0] == 1 );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask.value_data()[0] == 1.1 );
+
+    BOOST_UBLAS_DEBUG_TRACE( "Displaying matrix(1,1)" << matrix_mask(1,1) );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask(1,1) == 2.1 );
+
+    BOOST_UBLAS_DEBUG_TRACE( "Displaying matrix(0,1)" << matrix_mask(0,1) );
+    BOOST_UBLAS_TEST_CHECK( matrix_mask(0,1) == 1.1 );
+
+}
+
+int main()
+{
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_coordinate_matrix_sort );
+
+    BOOST_UBLAS_TEST_END();
+}
diff --git a/test/test_coordinate_vector_inplace_merge.cpp b/test/test_coordinate_vector_inplace_merge.cpp
new file mode 100644
index 0000000..9994e86
--- /dev/null
+++ b/test/test_coordinate_vector_inplace_merge.cpp
@@ -0,0 +1,109 @@
+//  Copyright (c) 2011 David Bellot
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
+# define BOOST_UBLAS_NO_ELEMENT_PROXIES
+#endif
+
+#include <boost/numeric/ublas/assignment.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/vector_sparse.hpp>
+#include <boost/numeric/ublas/vector_expression.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include "common/testhelper.hpp"
+#include "utils.hpp"
+
+const double TOL = 1e-15;
+
+template<typename T>
+bool check_sortedness(const boost::numeric::ublas::coordinate_vector<T>& vector) {
+  bool result = true;
+  typedef boost::numeric::ublas::coordinate_vector<T> vector_type;
+  typename vector_type::index_array_type idx = vector.index_data();
+  typename vector_type::size_type size = vector.filled();
+
+  for (typename vector_type::size_type i = 0; i + 1 < size && result; ++ i) {
+    result &= (idx[i] < idx[i + 1]);
+  }
+  return result;
+}
+
+void print_entries(size_t size,
+                   const std::vector<size_t>& entries)
+{
+  std::cerr << "Error entries - Size:" << size << ". Entries: ";
+  for (size_t i = 0; i < entries.size(); ++ i) {
+    std::cerr << entries[i] << "; ";
+  }
+  std::cerr << "\n";
+}
+
+BOOST_UBLAS_TEST_DEF( test_coordinate_vector_inplace_merge_random )
+{
+  const size_t max_repeats = 100;
+  const size_t max_size = 100;
+  const size_t dim_var = 10;
+  const size_t nr_entries = 10;
+
+  for (size_t repeats = 1; repeats < max_repeats; ++repeats ) {
+    for (size_t size = 1; size < max_size; size += 5) {
+      size_t size_vec = size + rand() % dim_var;
+
+      boost::numeric::ublas::coordinate_vector<double> vector_coord(size_vec);
+      boost::numeric::ublas::vector<double> vector_dense(size_vec, 0);
+
+      vector_coord.sort();
+
+      std::vector<size_t> entries;
+      for (size_t entry = 0; entry < nr_entries; ++ entry) {
+        int x = rand() % size_vec;
+        entries.push_back(x);
+        vector_coord.append_element(x, 1);
+        vector_dense(x) += 1;
+      }
+      vector_coord.sort();
+
+      {
+        bool sorted = check_sortedness(vector_coord);
+        bool identical = compare_to(vector_coord, vector_dense, TOL);
+        if (!(sorted && identical)) {
+          print_entries(size_vec, entries);
+        }
+        BOOST_UBLAS_TEST_CHECK( check_sortedness(vector_coord) );
+        BOOST_UBLAS_TEST_CHECK( compare_to(vector_coord, vector_dense, TOL) );
+      }
+
+      for (size_t entry = 0; entry < nr_entries; ++ entry) {
+        int x = rand() % size_vec;
+        entries.push_back(x);
+        vector_coord(x) += 1;
+        vector_dense(x) += 1;
+        vector_coord.sort();
+      }
+
+      {
+        bool sorted = check_sortedness(vector_coord);
+        bool identical = compare_to(vector_coord, vector_dense, TOL);
+        if (!(sorted && identical)) {
+          print_entries(size_vec, entries);
+        }
+        BOOST_UBLAS_TEST_CHECK( sorted );
+        BOOST_UBLAS_TEST_CHECK( identical );
+      }
+    }
+  }
+}
+
+int main()
+{
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_coordinate_vector_inplace_merge_random );
+
+    BOOST_UBLAS_TEST_END();
+
+    return EXIT_SUCCESS;;
+}
diff --git a/test/test_fixed_containers.cpp b/test/test_fixed_containers.cpp
new file mode 100644
index 0000000..23a6382
--- /dev/null
+++ b/test/test_fixed_containers.cpp
@@ -0,0 +1,309 @@
+#undef BOOST_UBLAS_NO_EXCEPTIONS
+#include "common/testhelper.hpp"
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/assignment.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <string>
+#include <sstream>
+#include <complex>
+#include <iomanip>
+#include "utils.hpp"
+
+#ifdef BOOST_UBLAS_CPP_GE_2011
+
+using namespace boost::numeric::ublas;
+
+using std::cout;
+using std::endl;
+
+template < class T >
+bool test_vector( std::string type_name)
+{
+    std::stringstream stream;
+    stream << "Testing for: " << type_name;
+    BOOST_UBLAS_DEBUG_TRACE( stream.str() );
+
+    bool pass = true;
+
+    {
+        typedef fixed_vector<T, 1> vec1;
+
+        vec1 v1( 122.0 );
+
+        pass &= ( v1(0) == (T)122 );
+
+    }
+
+    {
+        typedef fixed_vector<T, 3> vec3;
+
+        vec3 v1((T)0.0, (T)0.0, (T)0.0);
+
+        pass &=(sizeof( vec3 )  == v1.size()*sizeof( T ) ) ;
+
+        vector<T> v( 3, 0 ) ;
+
+        pass &= compare( v1, v );
+
+        v1 <<= 10.0, 10, 33;
+        v  <<= 10.0, 10, 33;
+
+        //cout << std::setprecision(20) << v1 << '\n' << v;
+
+        pass &= compare( v1, v );
+
+
+        vec3 v2;
+
+        v2( 0 ) = 10.0; v2( 1 ) = 10; v2( 2 ) = 33;
+        pass &= compare( v, v2 );
+
+        v2 += v;
+
+        pass &= compare( v2, 2*v );
+
+
+        v1 = 2*v1 + v - 6*v2;
+        pass &= compare( v1, (3-2*6)*v );
+
+
+        vec3 v3{ (T)-90.0, (T)-90.0, (T)-297.0 };
+        pass &= compare( v3, v1 );
+
+        vec3 v4 =  { (T)-90.0, (T)-90.0, (T)-297.0 };
+        pass &= compare( v4, v1 );
+
+        vec3 v5( (T)-90.0, (T)-90.0, (T)-297.0 );
+        pass &= compare( v5, v1 );
+
+        vec3 v6((T) 5.0, (T)8.0, (T)9.0);
+
+        matrix<T> M = outer_prod( v6, v6), L( 3, 3);
+
+        L <<= 25, 40, 45, 40, 64, 72, 45, 72, 81;
+
+        pass &= compare( M, L );
+
+        L  <<= 1, 2, 3, 4, 5, 6, 7, 8, 9;
+        v6 <<= 4, 5, 6;
+        vec3 v7 ( (T)32.0, (T)77.0, (T)122.0 );
+
+        pass &= compare( v7, prod(L, v6) );
+
+        vec3 v8;
+        noalias( v8 ) = prod(L, v6);
+
+        pass &= compare( v7, v8 );
+
+    }
+
+
+    {
+        const std::size_t N = 33;
+        typedef fixed_vector<T, N> vec33;
+
+        vec33 v1;
+        vector<T> v( N );
+
+        for ( std::size_t i = 0; i!= v1.size(); i++)
+        {
+            v1( i ) = 3.14159*i;
+            v ( i ) = 3.14159*i;
+        }
+
+        pass &= compare( v1, v );
+
+
+        auto ip = inner_prod( v, v);
+        auto ip1 = inner_prod( v1, v1);
+
+        pass &= (  ip == ip1 ) ;
+
+        T c = 0;
+        for (auto i = v1.begin(); i != v1.end(); i++)
+        {
+            *i = c;
+            c = c + 1;
+        }
+
+        c = 0;
+        for (auto i = v.begin(); i != v.end(); i++)
+        {
+            *i = c;
+            c = c + 1;
+        }
+
+        pass &= compare( v1, v );
+
+        // Check if bad index indeed works
+        try {
+            T a;
+            a=v1( 100 );
+            BOOST_UBLAS_NOT_USED( a );
+
+        } catch ( bad_index &e) {
+            std::cout << " Caught (GOOD): " << e.what() << endl;
+            pass &= true;
+        }
+
+
+    }
+    return pass;
+}
+
+template < class T >
+bool test_matrix( std::string type_name)
+{
+    std::stringstream stream;
+    stream << "Testing for: " << type_name;
+    BOOST_UBLAS_DEBUG_TRACE( stream.str() );
+
+    bool pass = true;
+
+    typedef fixed_matrix<T, 3, 4> mat34;
+    typedef fixed_matrix<T, 4, 3> mat43;
+    typedef fixed_matrix<T, 3, 3> mat33;
+
+
+    {
+        typedef fixed_matrix<T, 1, 1> mat1;
+
+        mat1 m1( 122.0 );
+
+        pass &= ( m1(0, 0) == (T)122 );
+    }
+
+
+    {
+        mat34 m1( 3.0 );
+
+        pass &=(sizeof( mat34 )  == m1.size1()*m1.size2()*sizeof( T ) ) ;
+
+        matrix<T> m( 3.0, 4.0, 3.0 ) ;
+
+        pass &= compare( m1, m );
+
+        cout << m1 << endl;
+        cout << m << endl;
+
+
+        m1 <<= 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
+        m  <<= 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
+
+        pass &= compare( m1, m );
+
+        cout << m1 << endl;
+        cout << m << endl;
+
+        mat34 m2( 0.0 );
+
+        T count = 1 ;
+        for ( std::size_t i = 0; i != m2.size1(); i++)
+        {
+            for (std::size_t j = 0; j!= m2.size2(); j++)
+            {
+                m2( i, j ) = count;
+                count = count + 1;
+            }
+
+        }
+        pass &= compare( m2, m );
+        cout << m2 << endl;
+
+    }
+    {
+        mat34 m1 = { (T)1, (T)2, (T)3, (T)3, (T)3, (T)2, (T)5, (T)4, (T)2, (T)6, (T)5, (T)2 };
+        mat43 m2 = { (T)4, (T)5, (T)6, (T)3, (T)2, (T)2, (T)1, (T)4, (T)2, (T)6, (T)5, (T)2 };
+
+        mat33 m3 = prod(m1, m2);
+
+        matrix<T> m(3, 3);
+        m <<= 31,36,22,47,59,40,43,52,38;
+
+        pass &= compare(m ,m3);
+
+        mat33 m4;
+        m4 <<= (T)1, (T)2, (T)1, (T)2, (T)1, (T)3, (T)1, (T)2, (T) 5;
+        m3  = prod(m4, trans(m4));
+
+        m<<=6,7,10,7,14,19,10,19,30;
+
+        cout << m3 << endl;
+        pass &= compare(m ,m3);
+
+        m3 = 2 * m4 - 1 * m3;
+
+        cout << m3;
+
+        m <<= -4,-3,-8,-3,-12,-13,-8,-15,-20;
+
+        pass &= compare(m, m3);
+
+        m = m3;
+
+        m3 = trans(m);
+
+        pass &= compare(m3, trans(m));
+
+        // Check if bad index indeed works
+        try {
+            T a;
+            a=m1( 100, 100 );
+            BOOST_UBLAS_NOT_USED( a );
+
+        } catch ( bad_index &e) {
+            std::cout << " Caught (GOOD): " << e.what() << endl;
+            pass &= true;
+        }
+
+    }
+
+    return pass;
+
+}
+
+BOOST_UBLAS_TEST_DEF (test_fixed) {
+
+    BOOST_UBLAS_DEBUG_TRACE( "Starting fixed container tests" );
+
+    BOOST_UBLAS_TEST_CHECK(  test_vector< double >( "double") );
+    BOOST_UBLAS_TEST_CHECK(  test_vector< float >( "float") );
+    BOOST_UBLAS_TEST_CHECK(  test_vector< int >( "int") );
+
+    BOOST_UBLAS_TEST_CHECK(  test_vector< std::complex<double> >( "std::complex<double>") );
+    BOOST_UBLAS_TEST_CHECK(  test_vector< std::complex<float> >( "std::complex<float>") );
+    BOOST_UBLAS_TEST_CHECK(  test_vector< std::complex<int> >( "std::complex<int>") );
+
+    BOOST_UBLAS_TEST_CHECK(  test_matrix< double >( "double") );
+    BOOST_UBLAS_TEST_CHECK(  test_matrix< float >( "float") );
+    BOOST_UBLAS_TEST_CHECK(  test_matrix< int >( "int") );
+
+    BOOST_UBLAS_TEST_CHECK(  test_matrix< std::complex<double> >( "std::complex<double>") );
+    BOOST_UBLAS_TEST_CHECK(  test_matrix< std::complex<float> >( "std::complex<float>") );
+    BOOST_UBLAS_TEST_CHECK(  test_matrix< std::complex<int> >( "std::complex<int>") );
+}
+
+
+int main () {
+
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_fixed );
+
+    BOOST_UBLAS_TEST_END();
+    return EXIT_SUCCESS;
+
+}
+
+#else
+
+int main () {
+
+    BOOST_UBLAS_TEST_BEGIN();
+    BOOST_UBLAS_TEST_END();
+
+    return EXIT_SUCCESS;
+
+}
+#endif // BOOST_UBLAS_CPP_GE_2011
diff --git a/test/test_inplace_solve.cpp b/test/test_inplace_solve.cpp
new file mode 100644
index 0000000..b2bf58d
--- /dev/null
+++ b/test/test_inplace_solve.cpp
@@ -0,0 +1,123 @@
+#include <iostream>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+#include "utils.hpp"
+
+namespace ublas  = boost::numeric::ublas;
+
+static const double TOL(1.0e-5); ///< Used for comparing two real numbers.
+static const int n(10);           ///< defines the test matrix size
+
+template<class mat, class vec>
+double diff(const mat& A, const vec& x, const vec& b) {
+    return ublas::norm_2(prod(A, x) - b);
+}
+
+// efficiently fill matrix depending on majority
+template<class mat>
+void fill_matrix(mat& A, ublas::column_major_tag) {
+    for (int i=0; i<n; ++i) {
+        if (i-1>=0) {
+            A(i-1, i) = -1;
+        }
+        A(i, i) = 1;
+        if (i+1<n) {
+            A(i+1, i) = -2;
+        }
+    }
+}
+template<class mat>
+void fill_matrix(mat& A, ublas::row_major_tag) {
+    for (int i=0; i<n; ++i) {
+        if (i-1>=0) {
+            A(i, i-1) = -1;
+        }
+        A(i, i) = 1;
+        if (i+1<n) {
+            A(i, i+1) = -2;
+        }
+    }
+}
+
+template<class mat>
+BOOST_UBLAS_TEST_DEF ( test_inplace_solve )
+{
+    mat A(n, n);
+    A.clear();
+    fill_matrix(A, typename mat::orientation_category());
+
+    ublas::vector<double>  b(n, 1.0);
+
+    // The test matrix is not triangular, but is interpreted that way by
+    // inplace_solve using the lower_tag/upper_tags. For checking, the
+    // triangular_adaptor makes A triangular for comparison.
+    {
+        ublas::vector<double>  x(b);
+        ublas::inplace_solve(A, x, ublas::lower_tag());
+        BOOST_UBLAS_TEST_CHECK(diff(ublas::triangular_adaptor<mat, ublas::lower>(A), x, b) < TOL);
+    }
+    {
+        ublas::vector<double>  x(b);
+        ublas::inplace_solve(A, x, ublas::upper_tag());
+        BOOST_UBLAS_TEST_CHECK(diff (ublas::triangular_adaptor<mat, ublas::upper>(A), x, b) < TOL);
+    }
+    {
+        ublas::vector<double>  x(b);
+        ublas::inplace_solve(x, A, ublas::lower_tag());
+        BOOST_UBLAS_TEST_CHECK(diff (trans(ublas::triangular_adaptor<mat, ublas::lower>(A)), x, b) < TOL);
+    }
+    {
+        ublas::vector<double>  x(b);
+        ublas::inplace_solve(x, A, ublas::upper_tag());
+        BOOST_UBLAS_TEST_CHECK(diff (trans(ublas::triangular_adaptor<mat, ublas::upper>(A)), x , b) < TOL);
+    }
+}
+
+int main() {
+
+    // typedefs are needed as macros do not work with "," in template arguments
+
+    BOOST_UBLAS_TEST_BEGIN();
+
+#ifdef USE_MATRIX
+    typedef ublas::matrix<double, ublas::row_major>     mat_doub_rowmaj;
+    typedef ublas::matrix<double, ublas::column_major>  mat_doub_colmaj;
+    BOOST_UBLAS_TEST_DO( test_inplace_solve<mat_doub_rowmaj> );
+    BOOST_UBLAS_TEST_DO( test_inplace_solve<mat_doub_colmaj> );
+#endif
+
+#ifdef USE_COMPRESSED_MATRIX
+    typedef ublas::compressed_matrix<double, ublas::row_major>  commat_doub_rowmaj;
+        typedef ublas::compressed_matrix<double, ublas::column_major>  commat_doub_colmaj;
+    BOOST_UBLAS_TEST_DO( test_inplace_solve<commat_doub_rowmaj> );
+    BOOST_UBLAS_TEST_DO( test_inplace_solve<commat_doub_colmaj> );
+#endif
+
+#ifdef USE_MAPPED_MATRIX
+    typedef ublas::mapped_matrix<double, ublas::row_major>      mapmat_doub_rowmaj;
+    typedef ublas::mapped_matrix<double, ublas::column_major>   mapmat_doub_colmaj;
+    BOOST_UBLAS_TEST_DO( test_inplace_solve<mapmat_doub_rowmaj> );
+    BOOST_UBLAS_TEST_DO( test_inplace_solve<mapmat_doub_colmaj> );
+#endif
+
+#ifdef USE_COORDINATE_MATRIX
+    typedef ublas::coordinate_matrix<double, ublas::row_major>     cormat_doub_rowmaj;
+    typedef ublas::coordinate_matrix<double, ublas::column_major>  cormat_doub_colmaj;
+    BOOST_UBLAS_TEST_DO( test_inplace_solve<cormat_doub_rowmaj> );
+    BOOST_UBLAS_TEST_DO( test_inplace_solve<cormat_doub_colmaj> );
+#endif
+
+#ifdef USE_MAPPED_VECTOR_OF_MAPPED_VECTOR
+    typedef ublas::mapped_vector_of_mapped_vector<double, ublas::row_major> mvmv_doub_rowmaj;
+    typedef ublas::mapped_vector_of_mapped_vector<double, ublas::column_major> mvmv_doub_colmaj;
+    BOOST_UBLAS_TEST_DO( test_inplace_solve<mvmv_doub_rowmaj> );
+    BOOST_UBLAS_TEST_DO( test_inplace_solve<mvmv_doub_colmaj> );
+#endif
+
+    BOOST_UBLAS_TEST_END();
+}
diff --git a/test/test_lu.cpp b/test/test_lu.cpp
new file mode 100644
index 0000000..e2b203f
--- /dev/null
+++ b/test/test_lu.cpp
@@ -0,0 +1,70 @@
+// Copyright 2008 Gunter Winkler <guwi17@gmx.de>
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// switch automatic singular check off
+#define BOOST_UBLAS_TYPE_CHECK 0
+
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/numeric/ublas/lu.hpp>
+#include <boost/cstdlib.hpp>
+
+#include "common/testhelper.hpp"
+
+#include <iostream>
+#include <sstream>
+
+using namespace boost::numeric::ublas;
+using std::string;
+
+static const string matrix_IN = "[3,3]((1,2,2),(2,3,3),(3,4,6))\0";
+static const string matrix_LU = "[3,3]((3,4,6),(3.33333343e-01,6.66666627e-01,0),(6.66666687e-01,4.99999911e-01,-1))\0";
+static const string matrix_INV= "[3,3]((-3,2,-7.94728621e-08),(1.50000012,0,-5.00000060e-01),(4.99999911e-01,-1,5.00000060e-01))\0";
+static const string matrix_PM = "[3](2,2,2)";
+
+int main () {
+
+  typedef float TYPE;
+
+  typedef matrix<TYPE> MATRIX;
+
+  MATRIX A;
+  MATRIX LU;
+  MATRIX INV;
+  
+  {
+    std::istringstream is(matrix_IN);
+    is >> A;
+  }
+  {
+    std::istringstream is(matrix_LU);
+    is >> LU;
+  }
+  {
+    std::istringstream is(matrix_INV);
+    is >> INV;
+  }
+  permutation_matrix<>::vector_type temp;
+  {
+    std::istringstream is(matrix_PM);
+    is >> temp;
+  }
+  permutation_matrix<> PM(temp);
+
+  permutation_matrix<> pm(3);
+    
+  int result = lu_factorize<MATRIX, permutation_matrix<> >(A, pm);
+
+  assertTrue("factorization completed: ", 0 == result);
+  assertTrue("LU factors are correct: ", compare(A, LU));
+  assertTrue("permutation is correct: ", compare(pm, PM));
+
+  MATRIX B = identity_matrix<TYPE>(A.size2());
+
+  lu_substitute(A, pm, B);
+
+  assertTrue("inverse is correct: ", compare(B, INV));    
+
+  return (getResults().second > 0) ? boost::exit_failure : boost::exit_success;
+}
diff --git a/test/test_matrix_vector.cpp b/test/test_matrix_vector.cpp
new file mode 100644
index 0000000..a7e8796
--- /dev/null
+++ b/test/test_matrix_vector.cpp
@@ -0,0 +1,458 @@
+//
+//  Copyright (c) 2013 Joaquim Duran
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/numeric/ublas/assignment.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_vector.hpp>
+#include "common/testhelper.hpp"
+#include "utils.hpp"
+
+using namespace boost::numeric::ublas;
+
+
+template <class Vector, class StorageCategory>
+void guardSparsePreserveResize( Vector &vec, typename Vector::size_type new_size, StorageCategory) // Because sparse matrices don't have preserve data implemented
+{
+    vec.resize( new_size );
+}
+
+
+template <class Vector>
+void guardSparsePreserveResize( Vector &vec, typename Vector::size_type new_size, sparse_tag) // Because sparse matrices don't have preserve data implemented
+{
+    vec.resize( new_size, false );
+}
+
+template <class Matrix>
+bool test_matrix_row_facade() {
+    bool pass = true;
+
+    typedef matrix_row_vector<Matrix> RowVector;
+
+    { // Testing resize
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: resize" );
+
+    typename Matrix::size_type num_rows = 3;
+    typename Matrix::size_type num_cols = 5;
+		
+    Matrix matrix(num_rows, num_cols);
+    RowVector rows(matrix);
+    pass &= (matrix.size1() == num_rows);
+    pass &= (rows.size() == num_rows);
+    pass &= (matrix.size2() == num_cols);
+	
+    typename Matrix::size_type new_num_rows = 6;
+    guardSparsePreserveResize( rows, new_num_rows, typename Matrix::storage_category());
+    //rows.resize(new_num_rows);
+
+    pass &= (matrix.size1() == new_num_rows);
+    pass &= (rows.size() == new_num_rows);
+    pass &= (matrix.size2() == num_cols);
+    }
+
+    { // Testing operator()
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: operator()" );
+
+    Matrix A(3,3), RA(3,3);
+    RowVector rows(A);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    for(typename Matrix::size_type i = 0; i < A.size1(); i++) {
+        rows(i) = matrix_row<Matrix>(RA, i);
+    }
+    
+    pass &= compare_to(A, RA);
+    }
+
+    { // Testing operator[]
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: operator[]" );
+
+    Matrix A(3,3), RA(3,3);
+    RowVector rows(A);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+		
+    for(typename Matrix::size_type i = 0; i < A.size1(); i++) {
+        rows[i] = matrix_row<Matrix>(RA, i);
+    }
+    
+    pass &= compare_to(A, RA);
+    }
+    
+    { // Testing operator[] const
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: operator[] const" );
+
+    Matrix RA(3,3);
+    RowVector rows(RA);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    for(typename Matrix::size_type i = 0; i < RA.size1(); i++) {
+      pass &= compare_to(rows[i], matrix_row<Matrix>(RA, i));
+    }
+    }
+
+    { // Testing const iterator
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: const iterator" );
+
+    Matrix RA(3,3);
+    RowVector rows(RA);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    typename RowVector::size_type i = 0;
+    for(typename RowVector::const_iterator iter = rows.begin();
+	iter != rows.end();
+	iter++) {
+      pass &= compare_to(*iter, matrix_row<Matrix>(RA, i++));
+    }
+    }
+
+    { // Testing iterator
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: iterator" );
+
+    Matrix A(3,3), RA(3,3);
+    RowVector rows(A);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    typename RowVector::size_type i = 0;
+    for(typename RowVector::iterator iter = rows.begin();
+	iter != rows.end();
+	iter++) {
+      *iter = matrix_row<Matrix>(RA, i++);
+    }
+
+    pass &= compare_to(A, RA);
+    }
+
+    { // Testing reserse iterator
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: reverse iterator" );
+
+    Matrix A(3,3), RA(3,3);
+    RowVector rows(A);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    typename RowVector::size_type i = rows.size();
+    for(typename RowVector::reverse_iterator iter = rows.rbegin();
+	iter != rows.rend();
+	iter++) {
+      *iter = matrix_row<Matrix>(RA, --i);
+    }
+
+    pass &= compare_to(A, RA);
+    }
+
+    { // Testing const reverse iterator
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_row_facade: const reverse iterator" );
+
+    Matrix RA(3,3);
+    RowVector rows(RA);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    typename RowVector::size_type i = rows.size();
+    for(typename RowVector::const_reverse_iterator iter = rows.rbegin();
+	iter != rows.rend();
+	iter++) {
+      pass &= compare_to(*iter, matrix_row<Matrix>(RA, --i));
+    }
+    }
+
+    return pass;
+}
+
+
+template <class Matrix>
+bool test_matrix_column_facade() {
+    bool pass = true;
+
+    typedef matrix_column_vector<Matrix> ColumnVector;
+
+    { // Testing resize
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: resize" );
+    typename Matrix::size_type num_rows = 5;
+    typename Matrix::size_type num_cols = 3;
+    
+    Matrix matrix(num_rows, num_cols);
+    ColumnVector columns(matrix);
+    pass &= (matrix.size2() == num_cols);
+    pass &= (columns.size() == num_cols);
+    pass &= (matrix.size1() == num_rows);
+	
+    typename Matrix::size_type new_num_cols = 6;
+    guardSparsePreserveResize( columns, new_num_cols, typename Matrix::storage_category());
+    //columns.resize(new_num_cols);
+    pass &= (matrix.size2() == new_num_cols);
+    pass &= (columns.size() == new_num_cols);
+    pass &= (matrix.size1() == num_rows);
+    }
+
+    { // Testing operator ()
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: operator()" );
+
+    Matrix A(3,3), RA(3,3);
+    ColumnVector columns(A);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+		
+    for(typename Matrix::size_type i = 0; i < A.size2(); i++) {
+        columns(i) = matrix_column<Matrix>(RA, i);
+    }
+    
+    pass &= compare_to(A, RA);
+    }
+
+    { // Testing operator[]
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: operator[]" );
+
+    Matrix A(3,3), RA(3,3);
+    ColumnVector columns(A);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+		
+    for(typename Matrix::size_type i = 0; i < A.size2(); i++) {
+        columns[i] = matrix_column<Matrix>(RA, i);
+    }
+    
+    pass &= compare_to(A, RA);
+    }
+    
+    { // Testing operator[] const
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: operator[] const" );
+
+    Matrix RA(3,3);
+    ColumnVector columns(RA);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    for(typename Matrix::size_type i = 0; i < RA.size2(); i++) {
+      pass &= compare_to(columns[i], matrix_column<Matrix>(RA, i));
+    }
+    }
+
+    { // Testing iterator
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: iterator" );
+
+     Matrix A(3,3), RA(3,3);
+    ColumnVector columns(A);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    typename ColumnVector::size_type i = 0;
+    for(typename ColumnVector::iterator iter = columns.begin();
+	iter != columns.end();
+	iter++) {
+      *iter = matrix_column<Matrix>(RA, i++);
+    }
+
+    pass &= compare_to(A, RA);
+    }
+
+    { // Testing const iterator
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: const iterator" );
+
+    Matrix RA(3,3);
+    ColumnVector columns(RA);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    typename ColumnVector::size_type i = 0;
+    for(typename ColumnVector::const_iterator iter = columns.begin();
+	iter != columns.end();
+	iter++) {
+      pass &= compare_to(*iter, matrix_column<Matrix>(RA, i++));
+    }
+    }
+
+    { // Testing reserse iterator
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: reverese iterator" );
+
+    Matrix A(3,3), RA(3,3);
+    ColumnVector columns(A);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    typename ColumnVector::size_type i = columns.size();
+    for(typename ColumnVector::reverse_iterator iter = columns.rbegin();
+	iter != columns.rend();
+	iter++) {
+      *iter = matrix_column<Matrix>(RA, --i);
+    }
+
+    pass &= compare_to(A, RA);
+    }
+
+    { // Testing const reverse iterator
+    BOOST_UBLAS_DEBUG_TRACE( "test_matrix_column_facade: const reverese iterator" );
+
+    Matrix RA(3,3);
+    ColumnVector columns(RA);
+
+    RA <<=  1, 2, 3,
+            4, 5, 6,
+            7, 8, 9;
+
+    typename ColumnVector::size_type i = columns.size();
+    for(typename ColumnVector::const_reverse_iterator iter = columns.rbegin();
+	iter != columns.rend();
+	iter++) {
+      pass &= compare_to(*iter, matrix_column<Matrix>(RA, --i));
+    }
+    }
+
+    return pass;
+}
+
+
+BOOST_UBLAS_TEST_DEF (test_matrix_row_facade) {
+
+    BOOST_UBLAS_DEBUG_TRACE( "Starting matrix row vector facade" );
+
+    BOOST_UBLAS_DEBUG_TRACE( "Testing matrix..." );
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<matrix<char> >());
+
+    BOOST_UBLAS_DEBUG_TRACE( "Testing bounded_matrix..." );
+    BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<double,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<float,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<long,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<unsigned long,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<int,7,7 > >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<unsigned int,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<char,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_row_facade<bounded_matrix<std::size_t,7, 7> >()));
+
+    BOOST_UBLAS_DEBUG_TRACE( "Testing mapped_matrix..." );
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<unsigned int> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<std::size_t> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<mapped_matrix<char> >());
+
+    BOOST_UBLAS_DEBUG_TRACE( "Testing compressed_matrix..." );
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<compressed_matrix<char> >());
+
+    BOOST_UBLAS_DEBUG_TRACE( "Testing coordinate_matrix..." );
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<long> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<unsigned long> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_row_facade<coordinate_matrix<char> >());
+}
+
+
+BOOST_UBLAS_TEST_DEF (test_matrix_column_facade) {
+
+    BOOST_UBLAS_DEBUG_TRACE( "Starting matrix row column facade" );
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<matrix<char> >());
+
+    BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<double,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<float,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<long,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<unsigned long,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<int,7,7 > >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<unsigned int,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<char,7, 7> >()));
+    BOOST_UBLAS_TEST_CHECK((test_matrix_column_facade<bounded_matrix<std::size_t,7, 7> >()));
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<unsigned int> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<std::size_t> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<mapped_matrix<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<unsigned long> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<compressed_matrix<char> >());
+
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<double> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<float> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<long> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<unsigned long> >())
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<unsigned int> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<std::size_t> >());
+    BOOST_UBLAS_TEST_CHECK(test_matrix_column_facade<coordinate_matrix<char> >());
+}
+
+
+int main () {
+    BOOST_UBLAS_TEST_BEGIN();
+
+    BOOST_UBLAS_TEST_DO( test_matrix_row_facade );
+    BOOST_UBLAS_TEST_DO( test_matrix_column_facade );
+
+    BOOST_UBLAS_TEST_END();
+
+    return EXIT_SUCCESS;;
+}
diff --git a/test/test_ticket7296.cpp b/test/test_ticket7296.cpp
new file mode 100644
index 0000000..65fdb4b
--- /dev/null
+++ b/test/test_ticket7296.cpp
@@ -0,0 +1,292 @@
+/**
+ * \file libs/numeric/ublas/test/test_utils.hpp
+ *
+ * \brief Test suite for utils.hpp.
+ *
+ * Copyright (c) 2012, Marco Guazzone
+ * 
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Marco Guazzone (marco.guazzone@gmail.com)
+ */
+
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <complex>
+#include <cstddef>
+#include "utils.hpp"
+
+
+namespace ublas = boost::numeric::ublas;
+
+
+static const double tol(1e-6);
+static const double mul(tol*10);
+
+
+BOOST_UBLAS_TEST_DEF( check )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: 'check'" );
+
+	BOOST_UBLAS_TEST_CHECK( true );
+}
+
+BOOST_UBLAS_TEST_DEF( check_eq )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: 'check_eq'" );
+
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." );
+	BOOST_UBLAS_TEST_CHECK_EQ( short(1), short(1) );
+	BOOST_UBLAS_TEST_CHECK_EQ( int(1), int(1) );
+	BOOST_UBLAS_TEST_CHECK_EQ( long(1), long(1) );
+	BOOST_UBLAS_TEST_CHECK_EQ( unsigned(1), unsigned(1) );
+
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." );
+	BOOST_UBLAS_TEST_CHECK_EQ( short(1), int(1) );
+	BOOST_UBLAS_TEST_CHECK_EQ( short(1), int(1) );
+	BOOST_UBLAS_TEST_CHECK_EQ( int(1), long(1) );
+	BOOST_UBLAS_TEST_CHECK_EQ( long(1), int(1) );
+
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test aliases." );
+	BOOST_UBLAS_TEST_CHECK_EQUAL( int(1), int(1) );
+}
+
+BOOST_UBLAS_TEST_DEF( check_close )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: 'check_close'" );
+
+	const double c1(1*mul);
+	const double c2(2*mul);
+
+	// Check T vs. T
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." );
+	BOOST_UBLAS_TEST_CHECK_CLOSE( float(c1), float(c1), tol );
+	BOOST_UBLAS_TEST_CHECK_CLOSE( double(c1), double(c1), tol );
+	BOOST_UBLAS_TEST_CHECK_CLOSE( ::std::complex<float>(c1,c2), ::std::complex<float>(c1,c2), tol );
+	BOOST_UBLAS_TEST_CHECK_CLOSE( ::std::complex<double>(c1,c2), ::std::complex<double>(c1,c2), tol );
+
+	// Check T1 vs. T2
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." );
+	BOOST_UBLAS_TEST_CHECK_CLOSE( float(c1), double(c1), tol );
+	BOOST_UBLAS_TEST_CHECK_CLOSE( double(c1), float(c1), tol );
+	BOOST_UBLAS_TEST_CHECK_CLOSE( ::std::complex<float>(c1,c2), ::std::complex<double>(c1,c2), tol );
+	BOOST_UBLAS_TEST_CHECK_CLOSE( ::std::complex<double>(c1,c2), ::std::complex<float>(c1,c2), tol );
+
+	// Check alias
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test aliases." );
+	BOOST_UBLAS_TEST_CHECK_PRECISION( float(c1), float(c1), tol );
+}
+
+BOOST_UBLAS_TEST_DEF( check_rel_close )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: 'check_rel_close'" );
+
+	const double c1(1*mul);
+	const double c2(2*mul);
+
+	// Check T vs. T
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." );
+	BOOST_UBLAS_TEST_CHECK_REL_CLOSE( float(c1), float(c1), tol );
+	BOOST_UBLAS_TEST_CHECK_REL_CLOSE( double(c1), double(c1), tol );
+	BOOST_UBLAS_TEST_CHECK_REL_CLOSE( ::std::complex<float>(c1,c2), ::std::complex<float>(c1,c2), tol );
+	BOOST_UBLAS_TEST_CHECK_REL_CLOSE( ::std::complex<double>(c1,c2), ::std::complex<double>(c1,c2), tol );
+
+	// Check T1 vs. T2
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." );
+	BOOST_UBLAS_TEST_CHECK_REL_CLOSE( float(c1), double(c1), tol );
+	BOOST_UBLAS_TEST_CHECK_REL_CLOSE( double(c1), float(c1), tol );
+	BOOST_UBLAS_TEST_CHECK_REL_CLOSE( ::std::complex<float>(c1,c2), ::std::complex<double>(c1,c2), tol );
+	BOOST_UBLAS_TEST_CHECK_REL_CLOSE( ::std::complex<double>(c1,c2), ::std::complex<float>(c1,c2), tol );
+
+	// Check alias
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test aliases." );
+	BOOST_UBLAS_TEST_CHECK_REL_PRECISION( float(c1), float(c1), tol );
+}
+
+BOOST_UBLAS_TEST_DEF( check_vector_eq )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: 'check_vector_eq'" );
+
+	const ::std::size_t n(5);
+
+	ublas::vector<short> sv = ublas::scalar_vector<short>(n, 1);
+	ublas::vector<int> iv = ublas::scalar_vector<int>(n, 1);
+	ublas::vector<long> lv = ublas::scalar_vector<long>(n, 1L);
+	ublas::vector<unsigned> uv = ublas::scalar_vector<unsigned>(n, 1u);
+
+	// Check T vs. T
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( sv, sv, n );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( iv, iv, n );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( lv, lv, n );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( uv, uv, n );
+
+	// Check T1 vs. T2
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( sv, iv, n );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( iv, sv, n );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( iv, lv, n );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_EQ( lv, iv, n );
+}
+
+BOOST_UBLAS_TEST_DEF( check_vector_close )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: 'check_vector_close'" );
+
+	const ::std::size_t n(5);
+
+	ublas::vector<float> fv = ublas::scalar_vector<float>(n, 1);
+	ublas::vector<float> dv = ublas::scalar_vector<float>(n, 1);
+	ublas::vector< ::std::complex<float> > cfv = ublas::scalar_vector< ::std::complex<float> >(n, ::std::complex<float>(1,2));
+	ublas::vector< ::std::complex<double> > cdv = ublas::scalar_vector< ::std::complex<double> >(n, ::std::complex<double>(1,2));
+
+	// Check T vs. T
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( fv, fv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( dv, dv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cfv, cfv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cdv, cdv, n, tol );
+
+	// Check T1 vs. T2
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( fv, dv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( dv, fv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cfv, cdv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE( cdv, cfv, n, tol );
+}
+
+BOOST_UBLAS_TEST_DEF( check_vector_rel_close )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: 'check_vector_rel_close'" );
+
+	const ::std::size_t n(5);
+	const double c1(1*mul);
+	const double c2(2*mul);
+
+	ublas::vector<float> fv = ublas::scalar_vector<float>(n, c1);
+	ublas::vector<double> dv = ublas::scalar_vector<double>(n, c1);
+	ublas::vector< ::std::complex<float> > cfv = ublas::scalar_vector< ::std::complex<float> >(n, ::std::complex<float>(c1,c2));
+	ublas::vector< ::std::complex<double> > cdv = ublas::scalar_vector< ::std::complex<double> >(n, ::std::complex<double>(c1,c2));
+
+	// Check T vs. T
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( fv, fv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( dv, dv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cfv, cfv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cdv, cdv, n, tol );
+
+	// Check T1 vs. T2
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( fv, dv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( dv, fv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cfv, cdv, n, tol );
+	BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE( cdv, cfv, n, tol );
+}
+
+BOOST_UBLAS_TEST_DEF( check_matrix_eq )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: 'check_matrix_eq'" );
+
+	const ::std::size_t nr(3);
+	const ::std::size_t nc(4);
+
+	ublas::matrix<short> sv = ublas::scalar_matrix<short>(nr, nc, 1);
+	ublas::matrix<int> iv = ublas::scalar_matrix<int>(nr, nc, 1);
+	ublas::matrix<long> lv = ublas::scalar_matrix<long>(nr, nc, 1L);
+	ublas::matrix<unsigned> uv = ublas::scalar_matrix<unsigned>(nr, nc, 1u);
+
+	// Check T vs. T
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( sv, sv, nr, nc );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( iv, iv, nr, nc );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( lv, lv, nr, nc );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( uv, uv, nr, nc );
+
+	// Check T1 vs. T2
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( sv, iv, nr, nc );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( iv, sv, nr, nc );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( iv, lv, nr, nc );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_EQ( lv, iv, nr, nc );
+}
+
+BOOST_UBLAS_TEST_DEF( check_matrix_close )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: 'check_matrix_close'" );
+
+	const ::std::size_t nr(3);
+	const ::std::size_t nc(4);
+	const double c1(1*mul);
+	const double c2(2*mul);
+
+	ublas::matrix<float> fA = ublas::scalar_matrix<float>(nr, nc, c1);
+	ublas::matrix<double> dA = ublas::scalar_matrix<double>(nr, nc, c1);
+	ublas::matrix< ::std::complex<float> > cfA = ublas::scalar_matrix< ::std::complex<float> >(nr, nc, ::std::complex<float>(c1,c2));
+	ublas::matrix< ::std::complex<double> > cdA = ublas::scalar_matrix< ::std::complex<double> >(nr, nc, ::std::complex<double>(c1,c2));
+
+	// Check T vs. T
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( fA, fA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( dA, dA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cfA, cfA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cdA, cdA, nr, nc, tol );
+
+	// Check T1 vs. T2
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( fA, dA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( dA, fA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cfA, cdA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE( cdA, cfA, nr, nc, tol );
+}
+
+
+BOOST_UBLAS_TEST_DEF( check_matrix_rel_close )
+{
+	BOOST_UBLAS_TEST_TRACE( "Test case: 'check_matrix_rel_close'" );
+
+	const ::std::size_t nr(3);
+	const ::std::size_t nc(4);
+	const double c1(1*mul);
+	const double c2(2*mul);
+
+	ublas::matrix<float> fA = ublas::scalar_matrix<float>(nr, nc, c1);
+	ublas::matrix<double> dA = ublas::scalar_matrix<double>(nr, nc, c1);
+	ublas::matrix< ::std::complex<float> > cfA = ublas::scalar_matrix< ::std::complex<float> >(nr, nc, ::std::complex<float>(c1,c2));
+	ublas::matrix< ::std::complex<double> > cdA = ublas::scalar_matrix< ::std::complex<double> >(nr, nc, ::std::complex<double>(c1,c2));
+
+	// Check T vs. T
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against same types." );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( fA, fA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( dA, dA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cfA, cfA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cdA, cdA, nr, nc, tol );
+
+	// Check T1 vs. T2
+	BOOST_UBLAS_DEBUG_TRACE( "-- Test against different types." );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( fA, dA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( dA, fA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cfA, cdA, nr, nc, tol );
+	BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE( cdA, cfA, nr, nc, tol );
+}
+
+
+int main()
+{
+	BOOST_UBLAS_TEST_SUITE( "Test 'utils.hpp' functionalities" );
+
+	BOOST_UBLAS_TEST_BEGIN();
+		BOOST_UBLAS_TEST_DO( check );
+		BOOST_UBLAS_TEST_DO( check_eq );
+		BOOST_UBLAS_TEST_DO( check_close );
+		BOOST_UBLAS_TEST_DO( check_rel_close );
+		BOOST_UBLAS_TEST_DO( check_vector_eq );
+		BOOST_UBLAS_TEST_DO( check_vector_close );
+		BOOST_UBLAS_TEST_DO( check_vector_rel_close );
+		BOOST_UBLAS_TEST_DO( check_matrix_eq );
+		BOOST_UBLAS_TEST_DO( check_matrix_close );
+		BOOST_UBLAS_TEST_DO( check_matrix_rel_close );
+	BOOST_UBLAS_TEST_END();
+}
diff --git a/test/test_triangular.cpp b/test/test_triangular.cpp
new file mode 100644
index 0000000..c6cba91
--- /dev/null
+++ b/test/test_triangular.cpp
@@ -0,0 +1,129 @@
+#include <iostream>
+#include <stdlib.h>
+#include <cmath>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+#include <boost/timer/timer.hpp>
+
+namespace ublas  = boost::numeric::ublas;
+
+template<class mat, class vec>
+double diff(const mat& A, const vec& x, const vec& b) {
+  vec temp(prod(A, x) - b);
+  double result = 0;
+  for (typename vec::size_type i=0; i<temp.size(); ++i) {
+    result += temp(i)*temp(i);
+  }
+  return std::sqrt(result);
+}
+
+template<class mat, class vec>
+double diff(const vec& x, const mat& A, const vec& b) {
+  return diff(trans(A), x, b);
+}
+
+namespace ublas  = boost::numeric::ublas;
+
+
+int main() {
+  const int n=7000;
+#if 1
+  ublas::compressed_matrix<double, ublas::row_major>     mat_row_upp(n, n);
+  ublas::compressed_matrix<double, ublas::column_major>  mat_col_upp(n, n);
+  ublas::compressed_matrix<double, ublas::row_major>     mat_row_low(n, n);
+  ublas::compressed_matrix<double, ublas::column_major>  mat_col_low(n, n);
+#else
+  ublas::matrix<double, ublas::row_major>     mat_row_upp(n, n, 0);
+  ublas::matrix<double, ublas::column_major>  mat_col_upp(n, n, 0);
+  ublas::matrix<double, ublas::row_major>     mat_row_low(n, n, 0);
+  ublas::matrix<double, ublas::column_major>  mat_col_low(n, n, 0);
+#endif
+  ublas::vector<double>  b(n, 1);
+
+  std::cerr << "Constructing..." << std::endl;
+  for (int i=0; i<n; ++i) {
+    b(i) = std::rand() % 10;
+    double main = -10 + std::rand() % 20 ;
+    if (main == 0) main+=1;
+    double side = -10 + std::rand() % 20 ;
+    if (i-1>=0) {
+      mat_row_low(i, i-1) = side;
+    }
+    mat_row_low(i, i) = main;
+
+    mat_col_low(i, i) = main;
+    if (i+1<n) {
+      mat_col_low(i+1, i) = side;
+    }
+
+    mat_row_upp(i, i) = main;
+    if (i+1<n) {
+      mat_row_upp(i, i+1) = side;
+    }
+
+    if (i-1>=0) {
+      mat_col_upp(i-1, i) = side;
+    }
+    mat_col_upp(i, i) = main;
+  }
+
+  std::cerr << "Starting..." << std::endl;
+  {
+    boost::timer::auto_cpu_timer t(std::cerr, "col_low x: %t sec CPU, %w sec real\n");
+    ublas::vector<double>  x(b);
+    ublas::inplace_solve(mat_col_low,  x, ublas::lower_tag());
+    std::cerr << "delta: " << diff(mat_col_low, x, b) << "\n";
+  }
+  {
+    boost::timer::auto_cpu_timer t(std::cerr, "row_low x: %t sec CPU, %w sec real\n");
+    ublas::vector<double>  x(b);
+    ublas::inplace_solve(mat_row_low, x, ublas::lower_tag());
+    std::cerr << "delta: " << diff(mat_row_low, x, b) << "\n";
+  }
+
+  {
+    boost::timer::auto_cpu_timer t(std::cerr, "col_upp x: %t sec CPU, %w sec real\n");
+    ublas::vector<double>  x(b);
+    ublas::inplace_solve(mat_col_upp,  x, ublas::upper_tag());
+    std::cerr << "delta: " << diff(mat_col_upp, x, b) << "\n";
+  }
+  {
+    boost::timer::auto_cpu_timer t(std::cerr, "row_upp x: %t sec CPU, %w sec real\n");
+    ublas::vector<double>  x(b);
+    ublas::inplace_solve(mat_row_upp, x, ublas::upper_tag());
+    std::cerr << "delta: " << diff(mat_row_upp, x, b) << "\n";
+  }
+
+  {
+    boost::timer::auto_cpu_timer t(std::cerr, "x col_low: %t sec CPU, %w sec real\n");
+    ublas::vector<double>  x(b);
+    ublas::inplace_solve(x, mat_col_low, ublas::lower_tag());
+    std::cerr << "delta: " << diff(x, mat_col_low, b) << "\n";
+  }
+  {
+    boost::timer::auto_cpu_timer t(std::cerr, "x row_low: %t sec CPU, %w sec real\n");
+    ublas::vector<double>  x(b);
+    ublas::inplace_solve(x, mat_row_low, ublas::lower_tag());
+    std::cerr << "delta: " << diff(x, mat_row_low, b) << "\n";
+  }
+
+  {
+    boost::timer::auto_cpu_timer t(std::cerr, "x col_upp: %t sec CPU, %w sec real\n");
+    ublas::vector<double>  x(b);
+    ublas::inplace_solve(x, mat_col_upp, ublas::upper_tag());
+    std::cerr << "delta: " << diff(x, mat_col_upp, b) << "\n";
+  }
+  {
+    boost::timer::auto_cpu_timer t(std::cerr, "x row_upp: %t sec CPU, %w sec real\n");
+    ublas::vector<double>  x(b);
+    ublas::inplace_solve(x, mat_row_upp, ublas::upper_tag());
+    std::cerr << "delta: " << diff(x, mat_row_upp, b) << "\n";
+  }
+
+
+}
diff --git a/test/triangular_access.cpp b/test/triangular_access.cpp
new file mode 100644
index 0000000..c2c9b77
--- /dev/null
+++ b/test/triangular_access.cpp
@@ -0,0 +1,220 @@
+/* Test program to test find functions of triagular matrices
+ *
+ * author: Gunter Winkler ( guwi17 at gmx dot de )
+ */
+// Copyright 2008 Gunter Winkler <guwi17@gmx.de>
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <boost/cstdlib.hpp>
+
+#include "common/testhelper.hpp"
+
+#ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+using boost::numeric::ublas::iterator1_tag;
+using boost::numeric::ublas::iterator2_tag;
+#endif
+
+template < class MAT >
+void test_iterator( MAT & A ) {
+
+#ifndef NOMESSAGES
+    std::cout << "=>";
+#endif
+  // check mutable iterators
+  typename MAT::iterator1 it1 = A.begin1();
+  typename MAT::iterator1 it1_end = A.end1();
+  
+  for ( ; it1 != it1_end; ++it1 ) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+    typename MAT::iterator2 it2 = it1.begin();
+    typename MAT::iterator2 it2_end = it1.end();
+#else
+    typename MAT::iterator2 it2 = begin(it1, iterator1_tag());
+    typename MAT::iterator2 it2_end = end(it1, iterator1_tag());
+#endif
+    for ( ; it2 != it2_end ; ++ it2 ) {
+#ifndef NOMESSAGES
+      std::cout << "( " << it2.index1() << ", " << it2.index2() << ") " << std::flush;
+#endif
+      * it2 = ( 10 * it2.index1() + it2.index2() );
+    }
+#ifndef NOMESSAGES
+    std::cout << std::endl;
+#endif
+  }
+
+}
+
+template < class MAT >
+void test_iterator2( MAT & A ) {
+
+#ifndef NOMESSAGES
+    std::cout << "=>";
+#endif
+  // check mutable iterators
+  typename MAT::iterator2 it2 = A.begin2();
+  typename MAT::iterator2 it2_end = A.end2();
+  
+  for ( ; it2 != it2_end; ++it2 ) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+    typename MAT::iterator1 it1 = it2.begin();
+    typename MAT::iterator1 it1_end = it2.end();
+#else
+    typename MAT::iterator1 it1 = begin(it2, iterator2_tag());
+    typename MAT::iterator1 it1_end = end(it2, iterator2_tag());
+#endif
+    for ( ; it1 != it1_end ; ++ it1 ) {
+#ifndef NOMESSAGES
+      std::cout << "( " << it1.index1() << ", " << it1.index2() << ") " << std::flush;
+#endif
+      * it1 = ( 10 * it1.index1() + it1.index2() );
+    }
+#ifndef NOMESSAGES
+    std::cout << std::endl;
+#endif
+  }
+
+}
+
+template < class MAT >
+typename MAT::value_type 
+test_iterator3( const MAT & A ) {
+
+#ifndef NOMESSAGES
+    std::cout << "=>";
+#endif
+  typename MAT::value_type result = 0;
+
+  // check mutable iterators
+  typename MAT::const_iterator1 it1 = A.begin1();
+  typename MAT::const_iterator1 it1_end = A.end1();
+  
+  for ( ; it1 != it1_end; ++it1 ) {
+#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
+    typename MAT::const_iterator2 it2 = it1.begin();
+    typename MAT::const_iterator2 it2_end = it1.end();
+#else
+    typename MAT::const_iterator2 it2 = begin(it1, iterator1_tag());
+    typename MAT::const_iterator2 it2_end = end(it1, iterator1_tag());
+#endif
+    for ( ; it2 != it2_end ; ++ it2 ) {
+#ifndef NOMESSAGES
+      std::cout << "( " << it2.index1() << ", " << it2.index2() << ") " << std::flush;
+#endif
+      result += * it2;
+    }
+#ifndef NOMESSAGES
+    std::cout << std::endl;
+#endif
+  }
+  return result;
+
+}
+
+
+int main () {
+    using namespace boost::numeric::ublas;
+
+    typedef double VALUE_TYPE;
+    typedef triangular_matrix<VALUE_TYPE, lower>        LT;
+    typedef triangular_matrix<VALUE_TYPE, unit_lower>   ULT;
+    typedef triangular_matrix<VALUE_TYPE, strict_lower> SLT;
+    typedef triangular_matrix<VALUE_TYPE, upper>        UT;
+    typedef triangular_matrix<VALUE_TYPE, unit_upper>   UUT;
+    typedef triangular_matrix<VALUE_TYPE, strict_upper> SUT;
+
+    LT A(5,5);
+
+    test_iterator(A);
+    test_iterator2(A);
+
+    ULT B(5,5);
+
+    test_iterator(B);
+    test_iterator2(B);
+
+    SLT C(5,5);
+
+    test_iterator(C);
+    test_iterator2(C);
+
+    UT D(5,5);
+
+    test_iterator(D);
+    test_iterator2(D);
+
+    UUT E(5,5);
+
+    test_iterator(E);
+    test_iterator2(E);
+
+    SUT F(5,5);
+
+    test_iterator(F);
+    test_iterator2(F);
+
+    assertTrue("Write access using iterators: ", true);
+
+    assertEquals(" LT: ",420.0,test_iterator3(A));
+    assertEquals("ULT: ",315.0,test_iterator3(B));
+    assertEquals("SLT: ",310.0,test_iterator3(C));
+    assertEquals(" UT: ",240.0,test_iterator3(D));
+    assertEquals("UUT: ",135.0,test_iterator3(E));
+    assertEquals("SUT: ",130.0,test_iterator3(F));
+
+    assertTrue("Read access using iterators: ", true);
+
+#ifndef NOMESSAGES
+    std::cout << A << B << C << D << E << F << std::endl;
+#endif
+
+    typedef matrix<VALUE_TYPE> MATRIX;
+    MATRIX mat(5,5);
+    triangular_adaptor<MATRIX, lower> lta((mat));
+    triangular_adaptor<MATRIX, unit_lower> ulta((mat));
+    triangular_adaptor<MATRIX, strict_lower> slta((mat));
+    triangular_adaptor<MATRIX, upper> uta((mat));
+    triangular_adaptor<MATRIX, unit_upper> uuta((mat));
+    triangular_adaptor<MATRIX, strict_upper> suta((mat));
+
+    test_iterator ( lta );
+    test_iterator2( lta );
+
+    test_iterator ( ulta );
+    test_iterator2( ulta );
+
+    test_iterator ( slta );
+    test_iterator2( slta );
+
+    test_iterator ( uta );
+    test_iterator2( uta );
+
+    test_iterator ( uuta );
+    test_iterator2( uuta );
+
+    test_iterator ( suta );
+    test_iterator2( suta );
+
+    assertTrue("Write access using adaptors: ", true);
+
+    assertEquals(" LTA: ",420.0,test_iterator3( lta ));
+    assertEquals("ULTA: ",315.0,test_iterator3( ulta ));
+    assertEquals("SLTA: ",310.0,test_iterator3( slta ));
+
+    assertEquals(" UTA: ",240.0,test_iterator3( uta ));
+    assertEquals("UUTA: ",135.0,test_iterator3( uuta ));
+    assertEquals("SUTA: ",130.0,test_iterator3( suta ));
+
+    assertTrue("Read access using adaptors: ", true);
+    
+#ifndef NOMESSAGES
+    std::cout << mat << std::endl;
+#endif
+
+    return (getResults().second > 0) ? boost::exit_failure : boost::exit_success;
+}
diff --git a/test/triangular_layout.cpp b/test/triangular_layout.cpp
new file mode 100644
index 0000000..815643d
--- /dev/null
+++ b/test/triangular_layout.cpp
@@ -0,0 +1,139 @@
+// Copyright 2008 Gunter Winkler <guwi17@gmx.de>
+// Thanks to Tiago Requeijo for providing this test
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <boost/numeric/ublas/symmetric.hpp>
+#include <boost/numeric/ublas/triangular.hpp>
+#include <boost/cstdlib.hpp>
+
+using namespace std;
+namespace ublas = boost::numeric::ublas;
+
+int main()
+{
+    int sz = 4;
+    ublas::symmetric_matrix<int, ublas::upper, ublas::column_major>  UpCol (sz, sz);
+    ublas::symmetric_matrix<int, ublas::upper, ublas::row_major>     UpRow (sz, sz);
+    ublas::symmetric_matrix<int, ublas::lower, ublas::column_major>  LoCol (sz, sz);
+    ublas::symmetric_matrix<int, ublas::lower, ublas::row_major>     LoRow (sz, sz);
+
+    ublas::triangular_matrix<int, ublas::upper, ublas::column_major>  TrUpCol (sz, sz);
+    ublas::triangular_matrix<int, ublas::upper, ublas::row_major>     TrUpRow (sz, sz);
+    ublas::triangular_matrix<int, ublas::lower, ublas::column_major>  TrLoCol (sz, sz);
+    ublas::triangular_matrix<int, ublas::lower, ublas::row_major>     TrLoRow (sz, sz);
+
+    for(int i=0; i<sz; ++i)
+        for(int j=i; j<sz; ++j)
+        {
+            // Symmetric
+            UpCol(i,j) = 10*i + j;
+            UpRow(i,j) = 10*i + j;
+            LoCol(i,j) = 10*i + j;
+            LoRow(i,j) = 10*i + j;
+            // Triangular
+            TrUpCol(i,j) = 10*i + j;
+            TrUpRow(i,j) = 10*i + j;
+            TrLoCol(j,i) = 10*i + j;
+            TrLoRow(j,i) = 10*i + j;
+        }
+
+    //get pointers to data
+    int* uc = &(UpCol.data()[0]);
+    int* ur = &(UpRow.data()[0]);
+    int* lc = &(LoCol.data()[0]);
+    int* lr = &(LoRow.data()[0]);
+    int* tuc = &(TrUpCol.data()[0]);
+    int* tur = &(TrUpRow.data()[0]);
+    int* tlc = &(TrLoCol.data()[0]);
+    int* tlr = &(TrLoRow.data()[0]);
+
+    // upper, column_major
+    //   storage should be:  0 1 11 2 12 22 3 13 23 33
+    int uc_correct[] = {0, 1, 11, 2, 12, 22, 3, 13, 23, 33};
+
+    // upper, row_major
+    //   storage should be:  0 1 2 3 11 12 13 22 23 33
+    int ur_correct[] = {0, 1, 2, 3, 11, 12, 13, 22, 23, 33};
+
+    // lower, column_major
+    //   storage should be:  0 1 2 3 11 12 13 22 23 33
+    int lc_correct[] = {0, 1, 2, 3, 11, 12, 13, 22, 23, 33};
+
+    // lower, row_major
+    //   storage should be:  0 1 11 2 12 22 3 13 23 33
+    int lr_correct[] = {0, 1, 11, 2, 12, 22, 3, 13, 23, 33};
+
+    bool success = true;
+
+    // Test Symmetric
+    for(int i=0; i<sz*(sz+1)/2; ++i)
+        if(uc[i] != uc_correct[i])
+        {
+            cout << "Storage error (Symmetric, Upper, Column major)" << endl;
+            success = false;
+            break;
+        }
+
+    for(int i=0; i<sz*(sz+1)/2; ++i)
+        if(ur[i] != ur_correct[i])
+        {
+            cout << "Storage error (Symmetric, Upper, Row major)" << endl;
+            success = false;
+            break;
+        }
+
+    for(int i=0; i<sz*(sz+1)/2; ++i)
+        if(lc[i] != lc_correct[i])
+        {
+            cout << "Storage error (Symmetric, Lower, Column major)" << endl;
+            success = false;
+            break;
+        }
+
+    for(int i=0; i<sz*(sz+1)/2; ++i)
+        if(lr[i] != lr_correct[i])
+        {
+            cout << "Storage error (Symmetric, Lower, Row major)" << endl;
+            success = false;
+            break;
+        }
+
+    // Test Triangular
+    for(int i=0; i<sz*(sz+1)/2; ++i)
+        if(tuc[i] != uc_correct[i])
+        {
+            cout << "Storage error (Triangular, Upper, Column major)" << endl;
+            success = false;
+            break;
+        }
+
+    for(int i=0; i<sz*(sz+1)/2; ++i)
+        if(tur[i] != ur_correct[i])
+        {
+            cout << "Storage error (Triangular, Upper, Row major)" << endl;
+            success = false;
+            break;
+        }
+
+    for(int i=0; i<sz*(sz+1)/2; ++i)
+        if(tlc[i] != lc_correct[i])
+        {
+            cout << "Storage error (Triangular, Lower, Column major)" << endl;
+            success = false;
+            break;
+        }
+
+    for(int i=0; i<sz*(sz+1)/2; ++i)
+        if(tlr[i] != lr_correct[i])
+        {
+            cout << "Storage error (Triangular, Lower, Row major)" << endl;
+            success = false;
+            break;
+        }
+
+        
+        return (success)?boost::exit_success:boost::exit_failure;
+}
diff --git a/test/utils.hpp b/test/utils.hpp
new file mode 100644
index 0000000..c1b69b9
--- /dev/null
+++ b/test/utils.hpp
@@ -0,0 +1,396 @@
+/**
+ * \file util.hpp
+ *
+ * \brief Utility macros/functions for testing and debugging purpose.
+ *
+ * Basic usage:
+ * <pre>
+ * BOOST_UBLAS_TEST_DEF( test_case_1 )
+ * {
+ *   // do your test stuff
+ * }
+ *
+ * BOOST_UBLAS_TEST_DEF( test_case_2 )
+ * {
+ *   // do your test stuff
+ * }
+ *
+ * // ...
+ *
+ * BOOST_UBLAS_TEST_DEF( test_case_n )
+ * {
+ *   // do your test stuff
+ * }
+ *
+ * int main()
+ * {
+ *   BOOST_UBLAS_TEST_SUITE( "My Test Suite" ); // optional
+ *
+ *   BOOST_UBLAS_TEST_BEGIN();
+ *     BOOST_UBLAS_TEST_DO( test_case_1 );
+ *     BOOST_UBLAS_TEST_DO( test_case_2 );
+ *     // ...
+ *     BOOST_UBLAS_TEST_DO( test_case_n );
+ *   BOOST_UBLAS_TEST_END();
+ * }
+ * </pre>
+ * Inside each <em>test_case_<code>k</code></em> you can use the various
+ * \c BOOST_UBLAS_TEST_CHECK* macros.
+ *
+ * <hr/>
+ *
+ *  Copyright (c) 2009-2012, Marco Guazzone
+ *
+ *  Distributed under the Boost Software License, Version 1.0. (See
+ *  accompanying file LICENSE_1_0.txt or copy at
+ *  http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * \author Marco Guazzone, marco.guazzone@gmail.com
+ */
+
+#ifndef BOOST_NUMERIC_UBLAS_TEST_UTILS_HPP
+#define BOOST_NUMERIC_UBLAS_TEST_UTILS_HPP
+
+
+#include <boost/numeric/ublas/detail/config.hpp>
+#include <boost/numeric/ublas/traits.hpp>
+
+#include <boost/math/special_functions/fpclassify.hpp> // isnan, isinf
+
+#include <cmath>
+#include <complex>
+#include <cstddef>
+#include <iostream>
+#include <limits>
+#include <stdexcept>
+
+#define BOOST_UBLAS_NOT_USED(x) (void)(x)
+
+namespace boost { namespace numeric { namespace ublas { namespace test { namespace detail { namespace /*<unnamed>*/ {
+
+  using ::std::abs;
+  using ::std::max;
+
+/// Check if the given complex number is a NaN.
+// read the comments in fpclassify as well
+template <typename T>
+BOOST_UBLAS_INLINE
+bool (isnan)(::std::complex<T> const& z)
+{
+	// According to IEEE, NaN is different even by itself
+  return (z != z) || (boost::math::isnan)(z.real()) || (boost::math::isnan)(z.imag());
+}
+
+/// Check if two (real) numbers are close each other (wrt a given tolerance).
+template <typename T1, typename T2, typename T3>
+BOOST_UBLAS_INLINE
+bool close_to(T1 x, T2 y, T3 tol)
+{
+	typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type,
+									T3>::promote_type real_type;
+
+    if ((boost::math::isnan)(x) || (boost::math::isnan)(y))
+    {
+        // According to IEEE, NaN is different even by itself
+        return false;
+    }
+    return abs(x-y) <= (max(static_cast<real_type>(abs(x)), static_cast<real_type>(abs(y)))*tol);
+}
+
+/// Check if two complex numbers are close each other (wrt a given tolerance).
+template <typename T1, typename T2, typename T3>
+BOOST_UBLAS_INLINE
+bool close_to(::std::complex<T1> const& x, ::std::complex<T2> const& y, T3 tol)
+{
+	typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type,
+									T3>::promote_type real_type;
+
+    if ((isnan)(x) || (isnan)(y))
+    {
+        // According to IEEE, NaN is different even by itself
+        return false;
+    }
+	::std::complex<real_type> xx(x);
+	::std::complex<real_type> yy(y);
+
+    return abs(xx-yy) <= (max(abs(xx), abs(yy))*tol);
+}
+
+/// Check if two (real) numbers are close each other (wrt a given tolerance).
+template <typename T1, typename T2, typename T3>
+BOOST_UBLAS_INLINE
+bool rel_close_to(T1 x, T2 y, T3 tol)
+{
+    //typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type,
+    //								T3>::promote_type real_type;
+
+    if ((boost::math::isnan)(x) || (boost::math::isnan)(y))
+    {
+        // According to IEEE, NaN is different even by itself
+        return false;
+    }
+    return abs(x-y)/abs(y) <= tol;
+}
+
+/// Check if two complex numbers are close each other (wrt a given tolerance).
+template <typename T1, typename T2, typename T3>
+BOOST_UBLAS_INLINE
+bool rel_close_to(::std::complex<T1> const& x, ::std::complex<T2> const& y, T3 tol)
+{
+	typedef typename promote_traits<typename promote_traits<T1,T2>::promote_type,
+									T3>::promote_type real_type;
+
+    if ((isnan)(x) || (isnan)(y))
+    {
+        // According to IEEE, NaN is different even by itself
+        return false;
+    }
+	::std::complex<real_type> xx(x);
+	::std::complex<real_type> yy(y);
+
+    return abs(xx-yy)/abs(yy) <= tol;
+}
+
+}}}}}} // Namespace boost::numeric::ublas::test::detail::<unnamed>
+
+
+/// Expand its argument \a x.
+#define BOOST_UBLAS_TEST_EXPAND_(x) x
+
+
+/// Expand its argument \a x inside parenthesis.
+#define BOOST_UBLAS_TEST_EXPANDP_(x) (x)
+
+
+/// Transform its argument \a x into a string.
+#define BOOST_UBLAS_TEST_STRINGIFY_(x) #x
+
+
+/// Concatenate its two \e string arguments \a x and \a y.
+#define BOOST_UBLAS_TEST_JOIN_(x,y) x ## y
+
+
+/// Output the message \a x if in debug-mode; otherwise output nothing.
+/// Note: we don't use macro expansion inside parenthesis to let \a m be an
+///  expression of the form <code>a &lt;&lt; b</code>.
+#ifndef NDEBUG
+# 	define BOOST_UBLAS_DEBUG_TRACE(x) ::std::cerr << "[Debug>> " << BOOST_UBLAS_TEST_EXPAND_(x) << ::std::endl
+#else
+# 	define BOOST_UBLAS_DEBUG_TRACE(x) /**/
+#endif // NDEBUG
+
+
+/// Define the name \a m of the entire test suite.
+#define BOOST_UBLAS_TEST_SUITE(m) ::std::cerr << "--- Test Suite: " << BOOST_UBLAS_TEST_EXPAND_(m) << " ---" << ::std::endl;
+
+
+/// Define the beginning of a test suite.
+#define BOOST_UBLAS_TEST_BEGIN() 	/* [BOOST_UBLAS_TEST_BEGIN] */ \
+									{ \
+										/* Begin of Test Suite */ \
+										::std::size_t test_fails__(0) \
+									/* [/BOOST_UBLAS_TEST_BEGIN] */
+
+
+/// Define a test case \a x inside the current test suite.
+#define BOOST_UBLAS_TEST_DEF(x) static void BOOST_UBLAS_TEST_EXPAND_(x)(::std::size_t& test_fails__)
+
+
+/// Call the test case \a x.
+#define BOOST_UBLAS_TEST_DO(x) 	/* [BOOST_UBLAS_TEST_DO] */ \
+								try \
+								{ \
+									BOOST_UBLAS_TEST_EXPAND_(x)(test_fails__); \
+								} \
+								catch (::std::exception& e) \
+								{ \
+									++test_fails__; \
+									BOOST_UBLAS_TEST_ERROR( e.what() ); \
+								} \
+								catch (...) \
+								{ \
+									++test_fails__; \
+								} \
+								/* [/BOOST_UBLAS_TEST_DO] */
+
+
+/// Define the end of a test suite and return non-zero value if any test failed.
+#define BOOST_UBLAS_TEST_END() 	/* [BOOST_UBLAS_TEST_END] */ \
+								if (test_fails__ > 0) \
+								{ \
+									::std::cerr << "Number of failed tests: " << test_fails__ << ::std::endl; \
+									return 1; \
+								} \
+								else \
+								{ \
+									::std::cerr << "No failed test" << ::std::endl; \
+									return 0; \
+								} \
+								} /* End of test suite */ \
+								/* [/BOOST_UBLAS_TEST_END] */
+
+
+/// Output the message \a m.
+/// Note: we don't use macro expansion inside parenthesis to let \a m be an
+///  expression of the form <code>a &lt;&lt; b</code>.
+#define BOOST_UBLAS_TEST_TRACE(m) ::std::cerr << "[Info>> " << BOOST_UBLAS_TEST_EXPAND_(m) << ::std::endl
+
+
+/// Check the truth of assertion \a x.
+#define BOOST_UBLAS_TEST_CHECK(x)	/* [BOOST_UBLAS_TEST_CHECK] */ \
+									if (!BOOST_UBLAS_TEST_EXPANDP_(x)) \
+									{ \
+										BOOST_UBLAS_TEST_ERROR( "Failed assertion: " << BOOST_UBLAS_TEST_STRINGIFY_(x) ); \
+										++test_fails__; \
+									} \
+									/* [/BOOST_UBLAS_TEST_CHECK] */
+
+
+/// Check for the equality of \a x against \a y.
+#define BOOST_UBLAS_TEST_CHECK_EQ(x,y)	/* [BOOST_UBLAS_TEST_CHECK_EQUAL] */ \
+										if (!(BOOST_UBLAS_TEST_EXPANDP_(x) == BOOST_UBLAS_TEST_EXPANDP_(y))) \
+										{ \
+											BOOST_UBLAS_TEST_ERROR( "Failed assertion: (" << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_STRINGIFY_(y) << ")" ); \
+											++test_fails__; \
+										} \
+										/* [/BOOST_UBLAS_TEST_CHECK_EQUAL] */
+
+
+/// Alias for macro \c BOOST_UBLAS_TEST_CHECK_EQ (for backward compatibility).
+#define BOOST_UBLAS_TEST_CHECK_EQUAL(x,y) BOOST_UBLAS_TEST_CHECK_EQ(x,y)
+
+
+/// Check that \a x and \a y are close with respect to a given precision \a e.
+#define BOOST_UBLAS_TEST_CHECK_CLOSE(x,y,e)	/* [BOOST_UBLAS_TEST_CHECK_CLOSE] */ \
+											if (!::boost::numeric::ublas::test::detail::close_to(BOOST_UBLAS_TEST_EXPAND_(x), BOOST_UBLAS_TEST_EXPAND_(y), BOOST_UBLAS_TEST_EXPAND_(e))) \
+											{ \
+												BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs(" << BOOST_UBLAS_TEST_STRINGIFY_(x) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " == " << BOOST_UBLAS_TEST_EXPANDP_(e) << "]" ); \
+												++test_fails__; \
+											} \
+											/* [/BOOST_UBLAS_TEST_CHECK_CLOSE] */
+
+
+/// Alias for macro \c BOOST_UBLAS_TEST_CHECK_CLOSE (for backward compatibility),
+#define BOOST_UBLAS_TEST_CHECK_PRECISION(x,y,e) BOOST_UBLAS_TEST_CHECK_CLOSE(x,y,e)
+
+
+/// Check that \a x is close to \a y with respect to a given relative precision \a e.
+#define BOOST_UBLAS_TEST_CHECK_REL_CLOSE(x,y,e)	/* [BOOST_UBLAS_TEST_CHECK_REL_CLOSE] */ \
+												if (!::boost::numeric::ublas::test::detail::rel_close_to(BOOST_UBLAS_TEST_EXPAND_(x), BOOST_UBLAS_TEST_EXPAND_(y), BOOST_UBLAS_TEST_EXPAND_(e))) \
+												{ \
+													BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ")/" << BOOST_UBLAS_TEST_STRINGIFY_(y) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e)  << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(e) << " == " << BOOST_UBLAS_TEST_EXPANDP_(e) << "]" ); \
+													++test_fails__; \
+												} \
+												/* [/BOOST_UBLAS_TEST_CHECK_REL_CLOSE] */
+
+
+/// Alias for macro \c BOOST_UBLAS_TEST_CHECK_REL_CLOSE (for backward compatibility),
+#define BOOST_UBLAS_TEST_CHECK_REL_PRECISION(x,y,e) BOOST_UBLAS_TEST_CHECK_REL_CLOSE(x,y,e)
+
+
+/// Check that elements of \a x and \a y are equal.
+#define BOOST_UBLAS_TEST_CHECK_VECTOR_EQ(x,y,n)	/* [BOOST_UBLAS_TEST_CHECK_VECTOR_EQ] */ \
+												if (BOOST_UBLAS_TEST_EXPANDP_(n) > 0) \
+												{ \
+													::std::size_t n__ = BOOST_UBLAS_TEST_EXPAND_(n); \
+													for (::std::size_t i__ = n__; i__ > 0; --i__) \
+													{ \
+														if (!(BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__]==BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__])) \
+														{ \
+															BOOST_UBLAS_TEST_ERROR( "Failed assertion: (" << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << "==" << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << ")" << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << " and " << BOOST_UBLAS_TEST_STRINGIFY_(n) << " == " << n__ << "]" ); \
+															++test_fails__; \
+														} \
+													} \
+												} \
+												/* [/BOOST_UBLAS_TEST_CHECK_VECTOR_EQ] */
+
+
+/// Check that elements of \a x and \a y are close with respect to a given precision \a e.
+#define BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE(x,y,n,e)	/* [BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE] */ \
+														if (BOOST_UBLAS_TEST_EXPANDP_(n) > 0) \
+														{ \
+															::std::size_t n__ = BOOST_UBLAS_TEST_EXPAND_(n); \
+															for (::std::size_t i__ = n__; i__ > 0; --i__) \
+															{ \
+																if (!::boost::numeric::ublas::test::detail::close_to(BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(e))) \
+																{ \
+																	BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e)  << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << " and " << BOOST_UBLAS_TEST_STRINGIFY_(n) << " == " << n__ << "]" ); \
+																	++test_fails__; \
+																} \
+															} \
+														} \
+														/* [/BOOST_UBLAS_TEST_CHECK_VECTOR_CLOSE] */
+
+
+/// Check that elements of \a x and \a y are close with respect to a given relative precision \a e.
+#define BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE(x,y,n,e)	/* [BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE] */ \
+														if (BOOST_UBLAS_TEST_EXPANDP_(n) > 0) \
+														{ \
+															::std::size_t n__ = BOOST_UBLAS_TEST_EXPAND_(n); \
+															for (::std::size_t i__ = n__; i__ > 0; --i__) \
+															{ \
+																if (!::boost::numeric::ublas::test::detail::rel_close_to(BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__], BOOST_UBLAS_TEST_EXPANDP_(e))) \
+																{ \
+																	BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e)  << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y[i__]) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)[n__-i__] << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << " and " << BOOST_UBLAS_TEST_STRINGIFY_(n) << " == " << n__ << "]" ); \
+																	++test_fails__; \
+																} \
+															} \
+														} \
+														/* [/BOOST_UBLAS_TEST_CHECK_VECTOR_REL_CLOSE] */
+
+
+/// Check that elements of matrices \a x and \a y are equal.
+#define BOOST_UBLAS_TEST_CHECK_MATRIX_EQ(x,y,nr,nc)	/* [BOOST_UBLAS_TEST_CHECK_MATRIX_EQ] */ \
+													for (::std::size_t i__ = 0; i__ < BOOST_UBLAS_TEST_EXPANDP_(nr); ++i__) \
+													{ \
+														for (::std::size_t j__ = 0; j__ < BOOST_UBLAS_TEST_EXPANDP_(nc); ++j__) \
+														{ \
+															if (!(BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__)==BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__))) \
+															{ \
+																BOOST_UBLAS_TEST_ERROR( "Failed assertion: (" << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << ") [with " << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << ", " << BOOST_UBLAS_TEST_STRINGIFY_(j__) << " == " << BOOST_UBLAS_TEST_EXPANDP_(j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(nr) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nr) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(nc) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nc) << "]" ); \
+																++test_fails__; \
+															} \
+														} \
+													} \
+													/* [/BOOST_UBLAS_TEST_CHECK_MATRIX_EQ] */
+
+
+/// Check that elements of matrices \a x and \a y are close with respect to a given precision \a e.
+#define BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE(x,y,nr,nc,e)	/* [BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE] */ \
+															for (::std::size_t i__ = 0; i__ < BOOST_UBLAS_TEST_EXPANDP_(nr); ++i__) \
+															{ \
+																for (::std::size_t j__ = 0; j__ < BOOST_UBLAS_TEST_EXPANDP_(nc); ++j__) \
+																{ \
+																	if (!::boost::numeric::ublas::test::detail::close_to(BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(e))) \
+																	{ \
+																		BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e)  << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << ", " << BOOST_UBLAS_TEST_STRINGIFY_(j__) << " == " << BOOST_UBLAS_TEST_EXPANDP_(j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(nr) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nr) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(nc) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nc) << "]" ); \
+																		++test_fails__; \
+																	} \
+																} \
+															} \
+															/* [/BOOST_UBLAS_TEST_CHECK_MATRIX_CLOSE] */
+
+
+/// Check that elements of matrices \a x and \a y are close with respect to a given relative precision \a e.
+#define BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE(x,y,nr,nc,e)	/* [BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE] */ \
+																for (::std::size_t i__ = 0; i__ < BOOST_UBLAS_TEST_EXPANDP_(nr); ++i__) \
+																{ \
+																	for (::std::size_t j__ = 0; j__ < BOOST_UBLAS_TEST_EXPANDP_(nc); ++j__) \
+																	{ \
+																		if (!::boost::numeric::ublas::test::detail::rel_close_to(BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__), BOOST_UBLAS_TEST_EXPANDP_(e))) \
+																		{ \
+																			BOOST_UBLAS_TEST_ERROR( "Failed assertion: abs((" << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << "-" << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << ") <= " << BOOST_UBLAS_TEST_STRINGIFY_(e)  << " [with " << BOOST_UBLAS_TEST_STRINGIFY_(x(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(x)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(y(i__,j__)) << " == " << BOOST_UBLAS_TEST_EXPANDP_(y)(i__,j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(i__) << " == " << i__ << ", " << BOOST_UBLAS_TEST_STRINGIFY_(j__) << " == " << BOOST_UBLAS_TEST_EXPANDP_(j__) << ", " << BOOST_UBLAS_TEST_STRINGIFY_(nr) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nr) << " and " << BOOST_UBLAS_TEST_STRINGIFY_(nc) << " == " << BOOST_UBLAS_TEST_EXPANDP_(nc) << "]" ); \
+																			++test_fails__; \
+																		} \
+																	} \
+																} \
+																/* [/BOOST_UBLAS_TEST_CHECK_MATRIX_REL_CLOSE] */
+
+///< Output the error message \a x.
+#ifdef _MSC_VER
+# define BOOST_UBLAS_TEST_ERROR(x) ::std::cerr << "[Error (" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << ")>> " << BOOST_UBLAS_TEST_EXPAND_(x) << ::std::endl
+#else
+# define BOOST_UBLAS_TEST_ERROR(x) ::std::cerr << "[Error (" << __FILE__ << ":" << __func__ << ":" << __LINE__ << ")>> " << BOOST_UBLAS_TEST_EXPAND_(x) << ::std::endl
+#endif
+
+#endif // BOOST_NUMERIC_UBLAS_TEST_UTILS_HPP