From 8df357b838370cb175700fd19ef0339cdf3b8dc4 Mon Sep 17 00:00:00 2001
From: "Timothy M. Shead" <tshead@sandia.gov>
Date: Tue, 30 Sep 2008 15:00:26 -0400
Subject: [PATCH] ENH: Finish adding sample N-Way array filters and tests.

---
 Filtering/vtkArrayData.h                      |   4 +
 Filtering/vtkArrayDataAlgorithm.h             |   3 +
 Filtering/vtkFactoredArrayData.h              |   3 +
 Filtering/vtkFactoredArrayDataAlgorithm.h     |   3 +
 Infovis/CMakeLists.txt                        |  29 +++
 .../Testing/Cxx/ArrayAPIDenseCoordinates.cxx  |  96 ++++++++
 Infovis/Testing/Cxx/ArrayCosineSimilarity.cxx |  94 ++++++++
 .../Testing/Cxx/ArrayDiagonalMatrixSource.cxx |  93 ++++++++
 .../Testing/Cxx/ArrayExtractFactoredArray.cxx |  68 ++++++
 Infovis/Testing/Cxx/ArrayMatricizeArray.cxx   |  94 ++++++++
 Infovis/Testing/Cxx/ArrayMatrixColumnNorm.cxx |  97 ++++++++
 .../Cxx/ArrayNormalizeMatrixVectors.cxx       | 115 +++++++++
 .../Testing/Cxx/ArrayTableToSparseArray.cxx   | 108 +++++++++
 Infovis/Testing/Cxx/ArrayTransposeMatrix.cxx  |  82 +++++++
 .../Testing/Cxx/BoostArrayLogWeighting.cxx    | 115 +++++++++
 .../Cxx/BoostArrayRandomSparseArraySource.cxx |  80 +++++++
 Infovis/Testing/Cxx/CMakeLists.txt            |  48 ++++
 Infovis/vtkAdjacencyMatrixToEdgeTable.cxx     | 163 +++++++++++++
 Infovis/vtkAdjacencyMatrixToEdgeTable.h       |  87 +++++++
 Infovis/vtkArrayToTable.cxx                   | 135 +++++++++++
 Infovis/vtkArrayToTable.h                     |  57 +++++
 Infovis/vtkBoostLogWeighting.cxx              |  88 +++++++
 Infovis/vtkBoostLogWeighting.h                |  56 +++++
 Infovis/vtkBoostRandomSparseArraySource.cxx   | 123 ++++++++++
 Infovis/vtkBoostRandomSparseArraySource.h     |  99 ++++++++
 Infovis/vtkCosineSimilarity.cxx               | 223 ++++++++++++++++++
 Infovis/vtkCosineSimilarity.h                 |  90 +++++++
 Infovis/vtkDiagonalMatrixSource.cxx           | 153 ++++++++++++
 Infovis/vtkDiagonalMatrixSource.h             |  97 ++++++++
 Infovis/vtkExtractFactoredArray.cxx           |  84 +++++++
 Infovis/vtkExtractFactoredArray.h             |  65 +++++
 Infovis/vtkMatricizeArray.cxx                 | 126 ++++++++++
 Infovis/vtkMatricizeArray.h                   |  77 ++++++
 Infovis/vtkMatrixColumnNorm.cxx               | 110 +++++++++
 Infovis/vtkMatrixColumnNorm.h                 |  64 +++++
 Infovis/vtkNormalizeMatrixVectors.cxx         | 108 +++++++++
 Infovis/vtkNormalizeMatrixVectors.h           |  63 +++++
 Infovis/vtkTableToSparseArray.cxx             | 178 ++++++++++++++
 Infovis/vtkTableToSparseArray.h               |  82 +++++++
 Infovis/vtkTransposeMatrix.cxx                | 118 +++++++++
 Infovis/vtkTransposeMatrix.h                  |  57 +++++
 41 files changed, 3635 insertions(+)
 create mode 100644 Infovis/Testing/Cxx/ArrayAPIDenseCoordinates.cxx
 create mode 100644 Infovis/Testing/Cxx/ArrayCosineSimilarity.cxx
 create mode 100644 Infovis/Testing/Cxx/ArrayDiagonalMatrixSource.cxx
 create mode 100644 Infovis/Testing/Cxx/ArrayExtractFactoredArray.cxx
 create mode 100644 Infovis/Testing/Cxx/ArrayMatricizeArray.cxx
 create mode 100644 Infovis/Testing/Cxx/ArrayMatrixColumnNorm.cxx
 create mode 100644 Infovis/Testing/Cxx/ArrayNormalizeMatrixVectors.cxx
 create mode 100644 Infovis/Testing/Cxx/ArrayTableToSparseArray.cxx
 create mode 100644 Infovis/Testing/Cxx/ArrayTransposeMatrix.cxx
 create mode 100644 Infovis/Testing/Cxx/BoostArrayLogWeighting.cxx
 create mode 100644 Infovis/Testing/Cxx/BoostArrayRandomSparseArraySource.cxx
 create mode 100644 Infovis/vtkAdjacencyMatrixToEdgeTable.cxx
 create mode 100644 Infovis/vtkAdjacencyMatrixToEdgeTable.h
 create mode 100644 Infovis/vtkArrayToTable.cxx
 create mode 100644 Infovis/vtkArrayToTable.h
 create mode 100644 Infovis/vtkBoostLogWeighting.cxx
 create mode 100644 Infovis/vtkBoostLogWeighting.h
 create mode 100644 Infovis/vtkBoostRandomSparseArraySource.cxx
 create mode 100644 Infovis/vtkBoostRandomSparseArraySource.h
 create mode 100644 Infovis/vtkCosineSimilarity.cxx
 create mode 100644 Infovis/vtkCosineSimilarity.h
 create mode 100644 Infovis/vtkDiagonalMatrixSource.cxx
 create mode 100644 Infovis/vtkDiagonalMatrixSource.h
 create mode 100644 Infovis/vtkExtractFactoredArray.cxx
 create mode 100644 Infovis/vtkExtractFactoredArray.h
 create mode 100644 Infovis/vtkMatricizeArray.cxx
 create mode 100644 Infovis/vtkMatricizeArray.h
 create mode 100644 Infovis/vtkMatrixColumnNorm.cxx
 create mode 100644 Infovis/vtkMatrixColumnNorm.h
 create mode 100644 Infovis/vtkNormalizeMatrixVectors.cxx
 create mode 100644 Infovis/vtkNormalizeMatrixVectors.h
 create mode 100644 Infovis/vtkTableToSparseArray.cxx
 create mode 100644 Infovis/vtkTableToSparseArray.h
 create mode 100644 Infovis/vtkTransposeMatrix.cxx
 create mode 100644 Infovis/vtkTransposeMatrix.h

diff --git a/Filtering/vtkArrayData.h b/Filtering/vtkArrayData.h
index 4fc5cb05bcc..2d39248b2fe 100644
--- a/Filtering/vtkArrayData.h
+++ b/Filtering/vtkArrayData.h
@@ -31,6 +31,10 @@ class vtkInformationVector;
 
 // .NAME vtkArrayData - Pipeline data object that acts as a container
 // for a single vtkArray
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
 class VTK_FILTERING_EXPORT vtkArrayData : public vtkDataObject
 {
 public:
diff --git a/Filtering/vtkArrayDataAlgorithm.h b/Filtering/vtkArrayDataAlgorithm.h
index 1700573d1da..43d88730064 100644
--- a/Filtering/vtkArrayDataAlgorithm.h
+++ b/Filtering/vtkArrayDataAlgorithm.h
@@ -39,6 +39,9 @@
 // signature. For even older filters that don't implement ExecuteData the
 // default implementation calls the even older Execute() signature.
 
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
 #ifndef __vtkArrayDataAlgorithm_h
 #define __vtkArrayDataAlgorithm_h
 
diff --git a/Filtering/vtkFactoredArrayData.h b/Filtering/vtkFactoredArrayData.h
index b629e245378..19801088a15 100644
--- a/Filtering/vtkFactoredArrayData.h
+++ b/Filtering/vtkFactoredArrayData.h
@@ -31,6 +31,9 @@ class vtkArray;
 // collection of vtkArray instances.  Used to store the "factored"
 // representation of a larger array.
 
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
 class VTK_FILTERING_EXPORT vtkFactoredArrayData : public vtkDataObject
 {
 public:
diff --git a/Filtering/vtkFactoredArrayDataAlgorithm.h b/Filtering/vtkFactoredArrayDataAlgorithm.h
index d74f6bffd81..c8515231ce7 100644
--- a/Filtering/vtkFactoredArrayDataAlgorithm.h
+++ b/Filtering/vtkFactoredArrayDataAlgorithm.h
@@ -39,6 +39,9 @@
 // signature. For even older filters that don't implement ExecuteData the
 // default implementation calls the even older Execute() signature.
 
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
 #ifndef __vtkFactoredArrayDataAlgorithm_h
 #define __vtkFactoredArrayDataAlgorithm_h
 
diff --git a/Infovis/CMakeLists.txt b/Infovis/CMakeLists.txt
index 58b0f6dfad2..e677252c07d 100644
--- a/Infovis/CMakeLists.txt
+++ b/Infovis/CMakeLists.txt
@@ -75,6 +75,7 @@ vtkXMLTreeReader.cxx
 
 # Add these classes only if using Boost
 IF(VTK_USE_BOOST)
+
   SET(Kit_SRCS
     ${Kit_SRCS}
     vtkBoostBiconnectedComponents.cxx
@@ -86,8 +87,36 @@ IF(VTK_USE_BOOST)
     vtkBoostPrimMinimumSpanningTree.cxx
     vtkBoostSplitTableField.cxx
   )
+
 ENDIF(VTK_USE_BOOST)
 
+IF(VTK_USE_N_WAY_ARRAYS)
+
+  SET(Kit_SRCS
+    ${Kit_SRCS}
+    vtkAdjacencyMatrixToEdgeTable.cxx
+    vtkArrayToTable.cxx
+    vtkCosineSimilarity.cxx
+    vtkDiagonalMatrixSource.cxx
+    vtkExtractFactoredArray.cxx
+    vtkMatricizeArray.cxx
+    vtkMatrixColumnNorm.cxx
+    vtkNormalizeMatrixVectors.cxx
+    vtkTableToSparseArray.cxx
+    vtkTransposeMatrix.cxx
+    )
+
+  IF(VTK_USE_BOOST)
+
+    SET(Kit_SRCS
+      ${Kit_SRCS}
+      vtkBoostLogWeighting.cxx
+      vtkBoostRandomSparseArraySource.cxx
+    )
+
+  ENDIF(VTK_USE_BOOST)
+ENDIF(VTK_USE_N_WAY_ARRAYS)
+
 # Add these classes only if vtkTypeUInt64Array exists
 SET(VTK_HAS_UINT64_ARRAY 0)
 IF(VTK_SIZEOF_LONG_LONG MATCHES "^8$")
diff --git a/Infovis/Testing/Cxx/ArrayAPIDenseCoordinates.cxx b/Infovis/Testing/Cxx/ArrayAPIDenseCoordinates.cxx
new file mode 100644
index 00000000000..14957875a05
--- /dev/null
+++ b/Infovis/Testing/Cxx/ArrayAPIDenseCoordinates.cxx
@@ -0,0 +1,96 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    ArrayAPIDenseCoordinates.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkDenseArray.h>
+#include <vtkDiagonalMatrixSource.h>
+#include <vtkSmartPointer.h>
+#include <vtkSparseArray.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+int ArrayAPIDenseCoordinates(int argc, char* argv[])
+{
+  try
+    {
+    vtkSmartPointer<vtkDiagonalMatrixSource> source = vtkSmartPointer<vtkDiagonalMatrixSource>::New();
+    source->SetExtents(3);
+    source->SetArrayType(vtkDiagonalMatrixSource::DENSE);
+    source->SetDiagonal(1.0);
+    source->SetSuperDiagonal(0.5);
+    source->SetSubDiagonal(-0.5);
+    source->Update();
+
+    vtkDenseArray<double>* const array = vtkDenseArray<double>::SafeDownCast(source->GetOutput()->GetArray());
+
+    cout << "dense diagonal matrix:\n";
+    vtkPrintMatrixFormat(cout, array);
+
+    cout << "dense diagonal coordinates:\n";
+    vtkPrintCoordinateFormat(cout, array);
+
+    test_expression(array);
+    test_expression(array->GetValue(vtkArrayCoordinates(0, 0)) == 1.0);
+    test_expression(array->GetValue(vtkArrayCoordinates(1, 0)) == -0.5);
+    test_expression(array->GetValue(vtkArrayCoordinates(2, 0)) == 0.0);
+    test_expression(array->GetValue(vtkArrayCoordinates(0, 1)) == 0.5);
+    test_expression(array->GetValue(vtkArrayCoordinates(1, 1)) == 1.0);
+    test_expression(array->GetValue(vtkArrayCoordinates(2, 1)) == -0.5);
+    test_expression(array->GetValue(vtkArrayCoordinates(0, 2)) == 0.0);
+    test_expression(array->GetValue(vtkArrayCoordinates(1, 2)) == 0.5);
+    test_expression(array->GetValue(vtkArrayCoordinates(2, 2)) == 1.0);
+
+    for(vtkIdType n = 0; n != array->GetNonNullSize(); ++n)
+      {
+      vtkArrayCoordinates coordinates;
+      array->GetCoordinatesN(n, coordinates);
+
+      if(coordinates[0] == 0 && coordinates[1] == 0)
+        {
+        test_expression(array->GetValueN(n) == 1.0);
+        }
+      else if(coordinates[0] == 0 && coordinates[1] == 1)
+        {
+        test_expression(array->GetValueN(n) == 0.5);
+        }
+      else if(coordinates[0] == 1 && coordinates[1] == 0)
+        {
+        test_expression(array->GetValueN(n) == -0.5);
+        }
+      }
+
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cerr << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/ArrayCosineSimilarity.cxx b/Infovis/Testing/Cxx/ArrayCosineSimilarity.cxx
new file mode 100644
index 00000000000..cf6778a8e6b
--- /dev/null
+++ b/Infovis/Testing/Cxx/ArrayCosineSimilarity.cxx
@@ -0,0 +1,94 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    ArrayCosineSimilarity.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkCosineSimilarity.h>
+#include <vtkDenseArray.h>
+#include <vtkSmartPointer.h>
+#include <vtkTable.h>
+#include <vtkVariant.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+static const bool close_enough(const double lhs, const double rhs)
+{
+  return fabs(lhs - rhs) < 1.0e-12;
+}
+
+int ArrayCosineSimilarity(int argc, char* argv[])
+{
+  cout << setprecision(17);
+  
+  try
+    {
+    vtkSmartPointer<vtkDenseArray<double> > source = vtkSmartPointer<vtkDenseArray<double> >::New();
+    source->Resize(vtkArrayExtents(2, 4));
+    source->SetValue(vtkArrayCoordinates(0, 0), 1);
+    source->SetValue(vtkArrayCoordinates(1, 0), 0);
+    source->SetValue(vtkArrayCoordinates(0, 1), 1);
+    source->SetValue(vtkArrayCoordinates(1, 1), 1);
+    source->SetValue(vtkArrayCoordinates(0, 2), 0);
+    source->SetValue(vtkArrayCoordinates(1, 2), 1);
+    source->SetValue(vtkArrayCoordinates(0, 3), -1);
+    source->SetValue(vtkArrayCoordinates(1, 3), 1);
+
+    cout << "source matrix:\n";
+    vtkPrintMatrixFormat(cout, source.GetPointer());
+    
+    vtkSmartPointer<vtkArrayData> source_data = vtkSmartPointer<vtkArrayData>::New();
+    source_data->SetArray(source);
+     
+    vtkSmartPointer<vtkCosineSimilarity> similarity = vtkSmartPointer<vtkCosineSimilarity>::New();
+    similarity->AddInputConnection(source_data->GetProducerPort());
+    similarity->SetVectorDimension(1);
+    similarity->Update();
+
+    vtkTable* const table = similarity->GetOutput();
+    test_expression(table->GetNumberOfColumns() == 3);
+
+    cout << "similarity table:\n";
+    for(vtkIdType row = 0; row < table->GetNumberOfRows(); ++row)
+      {
+      cout
+        << table->GetValue(row, 0).ToInt()
+        << " -> "
+        << table->GetValue(row, 1).ToInt()
+        << ": "
+        << table->GetValue(row, 2).ToDouble()
+        << "\n";
+      }
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cerr << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/ArrayDiagonalMatrixSource.cxx b/Infovis/Testing/Cxx/ArrayDiagonalMatrixSource.cxx
new file mode 100644
index 00000000000..bfadd68cdf9
--- /dev/null
+++ b/Infovis/Testing/Cxx/ArrayDiagonalMatrixSource.cxx
@@ -0,0 +1,93 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    ArrayDiagonalMatrixSource.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkDenseArray.h>
+#include <vtkDiagonalMatrixSource.h>
+#include <vtkSmartPointer.h>
+#include <vtkSparseArray.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+int ArrayDiagonalMatrixSource(int argc, char* argv[])
+{
+  try
+    {
+    vtkSmartPointer<vtkDiagonalMatrixSource> source = vtkSmartPointer<vtkDiagonalMatrixSource>::New();
+    source->SetExtents(3);
+    source->SetArrayType(vtkDiagonalMatrixSource::SPARSE);
+    source->SetDiagonal(1.0);
+    source->SetSuperDiagonal(0.5);
+    source->SetSubDiagonal(-0.5);
+    source->Update();
+
+    vtkSparseArray<double>* const sparse_array = vtkSparseArray<double>::SafeDownCast(source->GetOutput()->GetArray());
+    
+    cout << "sparse diagonal matrix:\n";
+    vtkPrintMatrixFormat(cout, sparse_array);
+
+    test_expression(sparse_array);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(0, 0)) == 1.0);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(1, 0)) == -0.5);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(2, 0)) == 0.0);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(0, 1)) == 0.5);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(1, 1)) == 1.0);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(2, 1)) == -0.5);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(0, 2)) == 0.0);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(1, 2)) == 0.5);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(2, 2)) == 1.0);
+
+    source->SetArrayType(vtkDiagonalMatrixSource::DENSE);
+    source->Update();
+
+    vtkDenseArray<double>* const dense_array = vtkDenseArray<double>::SafeDownCast(source->GetOutput()->GetArray());
+
+    cout << "dense diagonal matrix:\n";
+    vtkPrintMatrixFormat(cout, dense_array);
+
+    test_expression(dense_array);
+    test_expression(dense_array->GetValue(vtkArrayCoordinates(0, 0)) == 1.0);
+    test_expression(dense_array->GetValue(vtkArrayCoordinates(1, 0)) == -0.5);
+    test_expression(dense_array->GetValue(vtkArrayCoordinates(2, 0)) == 0.0);
+    test_expression(dense_array->GetValue(vtkArrayCoordinates(0, 1)) == 0.5);
+    test_expression(dense_array->GetValue(vtkArrayCoordinates(1, 1)) == 1.0);
+    test_expression(dense_array->GetValue(vtkArrayCoordinates(2, 1)) == -0.5);
+    test_expression(dense_array->GetValue(vtkArrayCoordinates(0, 2)) == 0.0);
+    test_expression(dense_array->GetValue(vtkArrayCoordinates(1, 2)) == 0.5);
+    test_expression(dense_array->GetValue(vtkArrayCoordinates(2, 2)) == 1.0);
+
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cerr << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/ArrayExtractFactoredArray.cxx b/Infovis/Testing/Cxx/ArrayExtractFactoredArray.cxx
new file mode 100644
index 00000000000..aec976cc5ec
--- /dev/null
+++ b/Infovis/Testing/Cxx/ArrayExtractFactoredArray.cxx
@@ -0,0 +1,68 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    ArrayExtractFactoredArray.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkExtractFactoredArray.h>
+#include <vtkFactoredArrayData.h>
+#include <vtkSmartPointer.h>
+#include <vtkSparseArray.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+int ArrayExtractFactoredArray(int argc, char* argv[])
+{
+  try
+    {
+    vtkSmartPointer<vtkSparseArray<double> > a = vtkSmartPointer<vtkSparseArray<double> >::New();
+    vtkSmartPointer<vtkSparseArray<double> > b = vtkSmartPointer<vtkSparseArray<double> >::New();
+
+    vtkSmartPointer<vtkFactoredArrayData> factored = vtkSmartPointer<vtkFactoredArrayData>::New();
+    factored->AddArray(a);
+    factored->AddArray(b);
+
+    vtkSmartPointer<vtkExtractFactoredArray> extract = vtkSmartPointer<vtkExtractFactoredArray>::New();
+    extract->AddInputConnection(factored->GetProducerPort());
+
+    extract->SetIndex(0);
+    extract->Update();
+    test_expression(extract->GetOutput()->GetArray() == a.GetPointer());
+
+    extract->SetIndex(1);
+    extract->Update();
+    test_expression(extract->GetOutput()->GetArray() == b.GetPointer());
+
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cout << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/ArrayMatricizeArray.cxx b/Infovis/Testing/Cxx/ArrayMatricizeArray.cxx
new file mode 100644
index 00000000000..f5186319110
--- /dev/null
+++ b/Infovis/Testing/Cxx/ArrayMatricizeArray.cxx
@@ -0,0 +1,94 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    ArrayMatricizeArray.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkMatricizeArray.h>
+#include <vtkSmartPointer.h>
+#include <vtkSparseArray.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+int ArrayMatricizeArray(int argc, char* argv[])
+{
+  try
+    {
+    // Create an array ...
+    vtkSmartPointer<vtkSparseArray<double> > array = vtkSmartPointer<vtkSparseArray<double> >::New();
+    array->Resize(vtkArrayExtents(2, 2, 2));
+
+    double value = 0;
+    const vtkArrayExtents extents = array->GetExtents();
+    for(int i = 0; i != extents[0]; ++i)
+      {
+      for(int j = 0; j != extents[1]; ++j)
+        {
+        for(int k = 0; k != extents[2]; ++k)
+          {
+          array->AddValue(vtkArrayCoordinates(i, j, k), value++);
+          }
+        }
+      }
+
+    cout << "array source:\n";
+    vtkPrintCoordinateFormat(cout, array.GetPointer());
+
+    // Create an array data object to hold it ...
+    vtkSmartPointer<vtkArrayData> array_data = vtkSmartPointer<vtkArrayData>::New();
+    array_data->SetArray(array);
+
+    // Matricize it ...
+    vtkSmartPointer<vtkMatricizeArray> matricize = vtkSmartPointer<vtkMatricizeArray>::New();
+    matricize->SetInput(array_data);
+    matricize->SetSliceDimension(0);
+    matricize->Update();
+
+    vtkSparseArray<double>* const matricized_array = vtkSparseArray<double>::SafeDownCast(matricize->GetOutput()->GetArray());
+    test_expression(matricized_array);
+
+    cout << "matricize output:\n";
+    vtkPrintCoordinateFormat(cout, matricized_array);
+
+    test_expression(matricized_array->GetValue(vtkArrayCoordinates(0, 0)) == 0);
+    test_expression(matricized_array->GetValue(vtkArrayCoordinates(0, 1)) == 1);
+    test_expression(matricized_array->GetValue(vtkArrayCoordinates(0, 2)) == 2);
+    test_expression(matricized_array->GetValue(vtkArrayCoordinates(0, 3)) == 3);
+    test_expression(matricized_array->GetValue(vtkArrayCoordinates(1, 0)) == 4);
+    test_expression(matricized_array->GetValue(vtkArrayCoordinates(1, 1)) == 5);
+    test_expression(matricized_array->GetValue(vtkArrayCoordinates(1, 2)) == 6);
+    test_expression(matricized_array->GetValue(vtkArrayCoordinates(1, 3)) == 7);
+
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cout << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/ArrayMatrixColumnNorm.cxx b/Infovis/Testing/Cxx/ArrayMatrixColumnNorm.cxx
new file mode 100644
index 00000000000..f3f237f5a78
--- /dev/null
+++ b/Infovis/Testing/Cxx/ArrayMatrixColumnNorm.cxx
@@ -0,0 +1,97 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    ArrayMatrixColumnNorm.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkMatrixColumnNorm.h>
+#include <vtkDenseArray.h>
+#include <vtkDiagonalMatrixSource.h>
+#include <vtkSmartPointer.h>
+#include <vtkSparseArray.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+static const bool close_enough(const double lhs, const double rhs)
+{
+  return fabs(lhs - rhs) < 1.0e-12;
+}
+
+int ArrayMatrixColumnNorm(int argc, char* argv[])
+{
+  cout << setprecision(17);
+  
+  try
+    {
+    vtkSmartPointer<vtkDiagonalMatrixSource> source = vtkSmartPointer<vtkDiagonalMatrixSource>::New();
+    source->SetExtents(3);
+    source->SetArrayType(vtkDiagonalMatrixSource::SPARSE);
+    source->SetDiagonal(1.0);
+    source->SetSuperDiagonal(0.5);
+    source->SetSubDiagonal(-0.5);
+    source->Update();
+
+    cout << "diagonal source:\n";
+    vtkPrintMatrixFormat(cout, vtkSparseArray<double>::SafeDownCast(source->GetOutput()->GetArray()));
+
+    vtkSmartPointer<vtkMatrixColumnNorm> vector_norm = vtkSmartPointer<vtkMatrixColumnNorm>::New();
+    vector_norm->AddInputConnection(source->GetOutputPort());
+    vector_norm->SetL(2);
+    vector_norm->Update();
+
+    vtkDenseArray<double>* const l2_norm = vtkDenseArray<double>::SafeDownCast(vector_norm->GetOutput()->GetArray());
+    
+    cout << "L2-norm:\n";
+    vtkPrintVectorFormat(cout, l2_norm);
+
+    test_expression(l2_norm);
+    test_expression(close_enough(l2_norm->GetValueN(0), 1.1180339887498949));
+    test_expression(close_enough(l2_norm->GetValueN(1), 1.2247448713915889));
+    test_expression(close_enough(l2_norm->GetValueN(2), 1.1180339887498949));
+
+    vector_norm->SetL(1);
+    vector_norm->Update();
+
+    vtkDenseArray<double>* const l1_norm = vtkDenseArray<double>::SafeDownCast(vector_norm->GetOutput()->GetArray());
+    
+    cout << "L1-norm:\n";
+    vtkPrintVectorFormat(cout, l1_norm);
+
+    test_expression(l1_norm);
+    test_expression(close_enough(l1_norm->GetValueN(0), 0.5));
+    test_expression(close_enough(l1_norm->GetValueN(1), 1.0));
+    test_expression(close_enough(l1_norm->GetValueN(2), 1.5));
+
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cerr << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/ArrayNormalizeMatrixVectors.cxx b/Infovis/Testing/Cxx/ArrayNormalizeMatrixVectors.cxx
new file mode 100644
index 00000000000..f0184ea6992
--- /dev/null
+++ b/Infovis/Testing/Cxx/ArrayNormalizeMatrixVectors.cxx
@@ -0,0 +1,115 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    ArrayNormalizeMatrixVectors.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkNormalizeMatrixVectors.h>
+#include <vtkDiagonalMatrixSource.h>
+#include <vtkSmartPointer.h>
+#include <vtkSparseArray.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+static const bool close_enough(const double lhs, const double rhs)
+{
+  return fabs(lhs - rhs) < 1.0e-12;
+}
+
+int ArrayNormalizeMatrixVectors(int argc, char* argv[])
+{
+  try
+    {
+    vtkSmartPointer<vtkDiagonalMatrixSource> source = vtkSmartPointer<vtkDiagonalMatrixSource>::New();
+    source->SetExtents(3);
+    source->SetArrayType(vtkDiagonalMatrixSource::SPARSE);
+    source->SetDiagonal(1.0);
+    source->SetSuperDiagonal(0.5);
+    source->SetSubDiagonal(-0.5);
+
+    cout << vtkstd::fixed << setprecision(1);
+    cout << "sparse diagonal source:\n";
+    source->Update();
+    vtkPrintMatrixFormat(cout, vtkTypedArray<double>::SafeDownCast(source->GetOutput()->GetArray()));
+
+    vtkSmartPointer<vtkNormalizeMatrixVectors> normalize = vtkSmartPointer<vtkNormalizeMatrixVectors>::New();
+    normalize->AddInputConnection(source->GetOutputPort());
+    normalize->SetVectorDimension(1);
+
+    normalize->Update();
+    vtkTypedArray<double>* normalized = vtkTypedArray<double>::SafeDownCast(normalize->GetOutput()->GetArray());
+    cout << vtkstd::fixed << setprecision(17);
+    cout << "sparse normalized:\n";
+    vtkPrintMatrixFormat(cout, normalized);
+
+    test_expression(normalized);
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(0, 0)), 0.89442719099991586));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(1, 0)), -0.44721359549995793));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(2, 0)), 0.00000000000000000));
+    
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(0, 1)), 0.40824829046386307));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(1, 1)), 0.81649658092772615));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(2, 1)), -0.40824829046386307));
+    
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(0, 2)), 0.00000000000000000));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(1, 2)), 0.44721359549995793));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(2, 2)), 0.89442719099991586));
+
+    source->SetArrayType(vtkDiagonalMatrixSource::DENSE);
+    cout << vtkstd::fixed << setprecision(1);
+    cout << "dense diagonal source:\n";
+    source->Update();
+    vtkPrintMatrixFormat(cout, vtkTypedArray<double>::SafeDownCast(source->GetOutput()->GetArray()));
+
+    normalize->Update();
+    normalized = vtkTypedArray<double>::SafeDownCast(normalize->GetOutput()->GetArray());
+    cout << vtkstd::fixed << setprecision(17);
+    cout << "dense normalized:\n";
+    vtkPrintMatrixFormat(cout, normalized);
+
+    test_expression(normalized);
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(0, 0)), 0.89442719099991586));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(1, 0)), -0.44721359549995793));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(2, 0)), 0.00000000000000000));
+    
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(0, 1)), 0.40824829046386307));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(1, 1)), 0.81649658092772615));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(2, 1)), -0.40824829046386307));
+    
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(0, 2)), 0.00000000000000000));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(1, 2)), 0.44721359549995793));
+    test_expression(close_enough(normalized->GetValue(vtkArrayCoordinates(2, 2)), 0.89442719099991586));
+
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cerr << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/ArrayTableToSparseArray.cxx b/Infovis/Testing/Cxx/ArrayTableToSparseArray.cxx
new file mode 100644
index 00000000000..608366a95a0
--- /dev/null
+++ b/Infovis/Testing/Cxx/ArrayTableToSparseArray.cxx
@@ -0,0 +1,108 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    ArrayTableToSparseArray.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkDoubleArray.h>
+#include <vtkIdTypeArray.h>
+#include <vtkSmartPointer.h>
+#include <vtkSparseArray.h>
+#include <vtkTable.h>
+#include <vtkTableToSparseArray.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+int ArrayTableToSparseArray(int argc, char* argv[])
+{
+  try
+    {
+    vtkSmartPointer<vtkIdTypeArray> i = vtkSmartPointer<vtkIdTypeArray>::New();
+    i->SetName("i");
+    
+    vtkSmartPointer<vtkIdTypeArray> j = vtkSmartPointer<vtkIdTypeArray>::New();
+    j->SetName("j");
+    
+    vtkSmartPointer<vtkIdTypeArray> k = vtkSmartPointer<vtkIdTypeArray>::New();
+    k->SetName("k");
+
+    vtkSmartPointer<vtkDoubleArray> value = vtkSmartPointer<vtkDoubleArray>::New();
+    value->SetName("value");
+    
+    vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
+    table->AddColumn(i);
+    table->AddColumn(j);
+    table->AddColumn(k);
+    table->AddColumn(value);
+
+    table->InsertNextBlankRow();
+    table->SetValue(0, 0, 0);
+    table->SetValue(0, 1, 0);
+    table->SetValue(0, 2, 0);
+    table->SetValue(0, 3, 1);
+
+    table->InsertNextBlankRow();
+    table->SetValue(1, 0, 1);
+    table->SetValue(1, 1, 2);
+    table->SetValue(1, 2, 3);
+    table->SetValue(1, 3, 2);
+      
+    table->InsertNextBlankRow();
+    table->SetValue(2, 0, 4);
+    table->SetValue(2, 1, 5);
+    table->SetValue(2, 2, 6);
+    table->SetValue(2, 3, 3);
+      
+    vtkSmartPointer<vtkTableToSparseArray> source = vtkSmartPointer<vtkTableToSparseArray>::New();
+    source->AddInputConnection(table->GetProducerPort());
+    source->AddCoordinateColumn("i");
+    source->AddCoordinateColumn("j");
+    source->AddCoordinateColumn("k");
+    source->SetValueColumn("value");
+    source->Update();
+
+    vtkSparseArray<double>* const sparse_array = vtkSparseArray<double>::SafeDownCast(source->GetOutput()->GetArray());
+    test_expression(sparse_array);
+
+    cout << "sparse array:\n";
+    vtkPrintCoordinateFormat(cout, sparse_array);
+    
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(0, 0, 0)) == 1);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(1, 2, 3)) == 2);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(4, 5, 6)) == 3);
+
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(0, 0, 1)) == 0);
+
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cerr << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/ArrayTransposeMatrix.cxx b/Infovis/Testing/Cxx/ArrayTransposeMatrix.cxx
new file mode 100644
index 00000000000..cdc6fc4d7ec
--- /dev/null
+++ b/Infovis/Testing/Cxx/ArrayTransposeMatrix.cxx
@@ -0,0 +1,82 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    ArrayTransposeMatrix.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkSmartPointer.h>
+#include <vtkSparseArray.h>
+#include <vtkTransposeMatrix.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+int ArrayTransposeMatrix(int argc, char* argv[])
+{
+  cout << setprecision(17);
+  
+  try
+    {
+    vtkSmartPointer<vtkSparseArray<double> > source = vtkSmartPointer<vtkSparseArray<double> >::New();
+    source->Resize(vtkArrayExtents(3, 2));
+    source->AddValue(vtkArrayCoordinates(0, 1), 1);
+    source->AddValue(vtkArrayCoordinates(1, 0), 2);
+    source->AddValue(vtkArrayCoordinates(2, 0), 3);
+
+    cout << "source matrix:\n";
+    vtkPrintMatrixFormat(cout, source.GetPointer());
+    
+    vtkSmartPointer<vtkArrayData> source_data = vtkSmartPointer<vtkArrayData>::New();
+    source_data->SetArray(source);
+     
+    vtkSmartPointer<vtkTransposeMatrix> transpose = vtkSmartPointer<vtkTransposeMatrix>::New();
+    transpose->AddInputConnection(source_data->GetProducerPort());
+    transpose->Update();
+
+    vtkSparseArray<double>* const output = vtkSparseArray<double>::SafeDownCast(transpose->GetOutput()->GetArray());
+    cout << "output matrix:\n";
+    vtkPrintMatrixFormat(cout, output);
+
+    test_expression(output);
+    test_expression(output->GetExtents()[0] = 2);
+    test_expression(output->GetExtents()[1] = 3);
+
+    test_expression(output->GetValue(vtkArrayCoordinates(0, 0)) == 0);
+    test_expression(output->GetValue(vtkArrayCoordinates(0, 1)) == 2);
+    test_expression(output->GetValue(vtkArrayCoordinates(0, 2)) == 3);
+    test_expression(output->GetValue(vtkArrayCoordinates(1, 0)) == 1);
+    test_expression(output->GetValue(vtkArrayCoordinates(1, 1)) == 0);
+    test_expression(output->GetValue(vtkArrayCoordinates(1, 2)) == 0);
+
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cerr << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/BoostArrayLogWeighting.cxx b/Infovis/Testing/Cxx/BoostArrayLogWeighting.cxx
new file mode 100644
index 00000000000..226f964369c
--- /dev/null
+++ b/Infovis/Testing/Cxx/BoostArrayLogWeighting.cxx
@@ -0,0 +1,115 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    BoostArrayLogWeighting.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkDiagonalMatrixSource.h>
+#include <vtkBoostLogWeighting.h>
+#include <vtkSmartPointer.h>
+#include <vtkTypedArray.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+static const bool close_enough(const double lhs, const double rhs)
+{
+  return fabs(lhs - rhs) < 1.0e-12;
+}
+
+int BoostArrayLogWeighting(int argc, char* argv[])
+{
+  try
+    {
+    vtkSmartPointer<vtkDiagonalMatrixSource> source = vtkSmartPointer<vtkDiagonalMatrixSource>::New();
+    source->SetExtents(3);
+    source->SetArrayType(vtkDiagonalMatrixSource::SPARSE);
+    source->SetSuperDiagonal(1.0);
+    source->SetDiagonal(3.0);
+    source->SetSubDiagonal(7.0);
+
+    cout << vtkstd::fixed << setprecision(1);
+    cout << "sparse diagonal source:\n";
+    source->Update();
+    vtkPrintMatrixFormat(cout, vtkTypedArray<double>::SafeDownCast(source->GetOutput()->GetArray()));
+
+    vtkSmartPointer<vtkBoostLogWeighting> log_weighting = vtkSmartPointer<vtkBoostLogWeighting>::New();
+    log_weighting->AddInputConnection(source->GetOutputPort());
+
+    log_weighting->Update();
+    vtkTypedArray<double>* weighted = vtkTypedArray<double>::SafeDownCast(log_weighting->GetOutput()->GetArray());
+    cout << vtkstd::fixed << setprecision(17);
+    cout << "sparse weighted:\n";
+    vtkPrintMatrixFormat(cout, weighted);
+
+
+    test_expression(weighted);
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(0, 0)), 1.38629436111989057));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(1, 0)), 2.07944154167983575));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(2, 0)), 0.0));
+    
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(0, 1)), 0.69314718055994529));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(1, 1)), 1.38629436111989057));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(2, 1)), 2.07944154167983575));
+    
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(0, 2)), 0.0));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(1, 2)), 0.69314718055994529));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(2, 2)), 1.38629436111989057));
+
+    source->SetArrayType(vtkDiagonalMatrixSource::DENSE);
+    cout << vtkstd::fixed << setprecision(1);
+    cout << "dense diagonal source:\n";
+    source->Update();
+    vtkPrintMatrixFormat(cout, vtkTypedArray<double>::SafeDownCast(source->GetOutput()->GetArray()));
+
+    log_weighting->Update();
+    weighted = vtkTypedArray<double>::SafeDownCast(log_weighting->GetOutput()->GetArray());
+    cout << vtkstd::fixed << setprecision(17);
+    cout << "dense weighted:\n";
+    vtkPrintMatrixFormat(cout, weighted);
+
+    test_expression(weighted);
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(0, 0)), 1.38629436111989057));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(1, 0)), 2.07944154167983575));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(2, 0)), 0.0));
+    
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(0, 1)), 0.69314718055994529));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(1, 1)), 1.38629436111989057));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(2, 1)), 2.07944154167983575));
+    
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(0, 2)), 0.0));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(1, 2)), 0.69314718055994529));
+    test_expression(close_enough(weighted->GetValue(vtkArrayCoordinates(2, 2)), 1.38629436111989057));
+
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cerr << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/BoostArrayRandomSparseArraySource.cxx b/Infovis/Testing/Cxx/BoostArrayRandomSparseArraySource.cxx
new file mode 100644
index 00000000000..9cd148b34fe
--- /dev/null
+++ b/Infovis/Testing/Cxx/BoostArrayRandomSparseArraySource.cxx
@@ -0,0 +1,80 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    BoostArrayRandomSparseArraySource.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include <vtkArrayData.h>
+#include <vtkArrayPrint.h>
+#include <vtkBoostRandomSparseArraySource.h>
+#include <vtkSmartPointer.h>
+#include <vtkSparseArray.h>
+
+#include <vtksys/ios/iostream>
+#include <vtksys/stl/stdexcept>
+
+#define test_expression(expression) \
+{ \
+  if(!(expression)) \
+    throw vtkstd::runtime_error("Expression failed: " #expression); \
+}
+
+static const bool close_enough(const double lhs, const double rhs)
+{
+  return fabs(lhs - rhs) < 1.0e-12;
+}
+
+int BoostArrayRandomSparseArraySource(int argc, char* argv[])
+{
+  try
+    {
+    vtkSmartPointer<vtkBoostRandomSparseArraySource> source = vtkSmartPointer<vtkBoostRandomSparseArraySource>::New();
+    source->SetExtents(vtkArrayExtents(2, 2, 2));
+    source->SetElementProbabilitySeed(123);
+    source->SetElementProbability(0.65);
+    source->SetElementValueSeed(456);
+    source->SetMinValue(-1.0);
+    source->SetMaxValue(1.0);
+    source->Update();
+
+    vtkSparseArray<double>* const sparse_array = vtkSparseArray<double>::SafeDownCast(source->GetOutput()->GetArray());
+    
+    cout << "sparse random source:\n";
+
+    cout << setprecision(17);
+    vtkPrintCoordinateFormat(cout, sparse_array);
+    
+    test_expression(sparse_array);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(0, 0, 0)) == 0.0);
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(0, 0, 1)) == 0.0);
+    test_expression(close_enough(sparse_array->GetValue(vtkArrayCoordinates(0, 1, 0)), -0.67386643076315522));
+    test_expression(close_enough(sparse_array->GetValue(vtkArrayCoordinates(0, 1, 1)), -0.69691725401207805));
+    test_expression(close_enough(sparse_array->GetValue(vtkArrayCoordinates(1, 0, 0)), 0.56728651095181704));
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(1, 0, 1)) == 0.0);
+    test_expression(close_enough(sparse_array->GetValue(vtkArrayCoordinates(1, 1, 0)), 0.61704678647220135));
+    test_expression(sparse_array->GetValue(vtkArrayCoordinates(1, 1, 1)) == 0.0);
+
+    return 0;
+    }
+  catch(vtkstd::exception& e)
+    {
+    cerr << e.what() << endl;
+    return 1;
+    }
+}
+
diff --git a/Infovis/Testing/Cxx/CMakeLists.txt b/Infovis/Testing/Cxx/CMakeLists.txt
index e5c79cff554..6bb52ae160a 100644
--- a/Infovis/Testing/Cxx/CMakeLists.txt
+++ b/Infovis/Testing/Cxx/CMakeLists.txt
@@ -123,3 +123,51 @@ IF (VTK_USE_RENDERING AND VTK_USE_DISPLAY)
     ENDIF (VTK_DATA_ROOT)
   ENDFOREACH (test) 
 ENDIF (VTK_USE_RENDERING AND VTK_USE_DISPLAY)
+
+
+IF(VTK_USE_N_WAY_ARRAYS)
+
+  CREATE_TEST_SOURCELIST(ArrayTests ArrayCxxTests.cxx
+    ArrayAPIDenseCoordinates.cxx
+    ArrayCosineSimilarity.cxx
+    ArrayDiagonalMatrixSource.cxx
+    ArrayExtractFactoredArray.cxx
+    ArrayMatricizeArray.cxx
+    ArrayMatrixColumnNorm.cxx
+    ArrayNormalizeMatrixVectors.cxx
+    ArrayTableToSparseArray.cxx
+    ArrayTransposeMatrix.cxx
+    )
+
+  ADD_EXECUTABLE(InfovisArrayCxxTests ${ArrayTests})
+  TARGET_LINK_LIBRARIES(InfovisArrayCxxTests vtkInfovis)
+
+  SET(ArrayTestsToRun ${ArrayTests})
+  REMOVE(ArrayTestsToRun ArrayCxxTests.cxx)
+
+  FOREACH(test ${ArrayTestsToRun})
+    GET_FILENAME_COMPONENT(TName ${test} NAME_WE)
+    ADD_TEST(Array-${TName} ${CXX_TEST_PATH}/InfovisArrayCxxTests ${TName})
+  ENDFOREACH(test)
+
+  IF(VTK_USE_BOOST)
+
+    CREATE_TEST_SOURCELIST(BoostArrayTests BoostArrayCxxTests.cxx
+      BoostArrayLogWeighting.cxx
+      BoostArrayRandomSparseArraySource.cxx
+      )
+
+    ADD_EXECUTABLE(InfovisBoostArrayCxxTests ${BoostArrayTests})
+    TARGET_LINK_LIBRARIES(InfovisBoostArrayCxxTests vtkInfovis)
+
+    SET(BoostArrayTestsToRun ${BoostArrayTests})
+    REMOVE(BoostArrayTestsToRun BoostArrayCxxTests.cxx)
+
+    FOREACH(test ${BoostArrayTestsToRun})
+      GET_FILENAME_COMPONENT(TName ${test} NAME_WE)
+      ADD_TEST(Boost-Array-${TName} ${CXX_TEST_PATH}/InfovisBoostArrayCxxTests ${TName})
+    ENDFOREACH(test)
+
+  ENDIF(VTK_USE_BOOST)
+ENDIF(VTK_USE_N_WAY_ARRAYS)
+
diff --git a/Infovis/vtkAdjacencyMatrixToEdgeTable.cxx b/Infovis/vtkAdjacencyMatrixToEdgeTable.cxx
new file mode 100644
index 00000000000..b1d06f6a13d
--- /dev/null
+++ b/Infovis/vtkAdjacencyMatrixToEdgeTable.cxx
@@ -0,0 +1,163 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkAdjacencyMatrixToEdgeTable.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkArrayData.h"
+#include "vtkAdjacencyMatrixToEdgeTable.h"
+#include "vtkCommand.h"
+#include "vtkDenseArray.h"
+#include "vtkDoubleArray.h"
+#include "vtkIdTypeArray.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkTable.h"
+
+#include <vtksys/stl/map>
+
+// ----------------------------------------------------------------------
+
+vtkCxxRevisionMacro(vtkAdjacencyMatrixToEdgeTable, "1.1");
+vtkStandardNewMacro(vtkAdjacencyMatrixToEdgeTable);
+
+// ----------------------------------------------------------------------
+
+vtkAdjacencyMatrixToEdgeTable::vtkAdjacencyMatrixToEdgeTable() :
+  SourceDimension(0),
+  ValueArrayName(0),
+  MinimumCount(0),
+  MinimumThreshold(0.5)
+{
+  this->SetValueArrayName("value");
+  
+  this->SetNumberOfInputPorts(1);
+  this->SetNumberOfOutputPorts(1);
+}
+
+// ----------------------------------------------------------------------
+
+vtkAdjacencyMatrixToEdgeTable::~vtkAdjacencyMatrixToEdgeTable()
+{
+  this->SetValueArrayName(0);
+}
+
+// ----------------------------------------------------------------------
+
+void vtkAdjacencyMatrixToEdgeTable::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "SourceDimension: " << this->SourceDimension << endl;
+  os << indent << "ValueArrayName: " << (this->ValueArrayName ? this->ValueArrayName : "") << endl;
+  os << indent << "MinimumCount: " << this->MinimumCount << endl;
+  os << indent << "MinimumThreshold: " << this->MinimumThreshold << endl;
+}
+
+int vtkAdjacencyMatrixToEdgeTable::FillInputPortInformation(int port, vtkInformation* info)
+{
+  switch(port)
+    {
+    case 0:
+      info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkArrayData");
+      return 1;
+    }
+
+  return 0;
+}
+
+// ----------------------------------------------------------------------
+
+int vtkAdjacencyMatrixToEdgeTable::RequestData(
+  vtkInformation*, 
+  vtkInformationVector** inputVector, 
+  vtkInformationVector* outputVector)
+{
+  vtkArrayData* const input = vtkArrayData::GetData(inputVector[0]);
+  vtkDenseArray<double>* const input_array = vtkDenseArray<double>::SafeDownCast(input->GetArray());
+  if(!input_array)
+    {
+    vtkErrorMacro(<< "vtkAdjacencyMatrixToEdgeTable requires an input vtkDenseArray<double>");
+    return 0;
+    }
+  if(input_array->GetDimensions() != 2)
+    {
+    vtkErrorMacro(<< "vtkAdjacencyMatrixToEdgeTable requires an input matrix.");
+    return 0;
+    }
+
+  const vtkArrayExtents input_extents = input_array->GetExtents();
+
+  const vtkIdType source_dimension = vtkstd::max(static_cast<vtkIdType>(0), vtkstd::min(static_cast<vtkIdType>(1), this->SourceDimension));
+  const vtkIdType target_dimension = 1 - source_dimension;
+
+  vtkTable* const output_table = vtkTable::GetData(outputVector);
+
+  vtkIdTypeArray* const source_array = vtkIdTypeArray::New();
+  source_array->SetName(input_array->GetDimensionLabel(source_dimension));
+
+  vtkIdTypeArray* const target_array = vtkIdTypeArray::New();
+  target_array->SetName(input_array->GetDimensionLabel(target_dimension));
+
+  vtkDoubleArray* const value_array = vtkDoubleArray::New();
+  value_array->SetName(this->ValueArrayName);
+
+  // For each source in the matrix ...
+  vtkArrayCoordinates coordinates(0, 0);
+  for(vtkIdType i = 0; i != input_extents[source_dimension]; ++i)
+    {
+    coordinates[source_dimension] = i;
+
+    // Create a sorted list of source values ...
+    typedef vtkstd::map<double, vtkIdType, vtkstd::greater<double> > sorted_values_t;
+    sorted_values_t sorted_values;
+    for(vtkIdType j = 0; j != input_extents[target_dimension]; ++j)
+      {
+      coordinates[target_dimension] = j;
+      sorted_values.insert(vtkstd::make_pair(input_array->GetValue(coordinates), j));
+      }
+
+    // Create edges for each value that meets our count / threshold criteria ...
+    vtkIdType count = 0;
+    for(sorted_values_t::const_iterator value = sorted_values.begin(); value != sorted_values.end(); ++value, ++count)
+      {
+      if(count < this->MinimumCount || value->first >= this->MinimumThreshold)
+        {
+        source_array->InsertNextValue(i);
+        target_array->InsertNextValue(value->second);
+        value_array->InsertNextValue(value->first);
+        }
+      }
+
+    double progress = static_cast<double>(i) / static_cast<double>(input_extents[source_dimension]);
+    this->InvokeEvent(vtkCommand::ProgressEvent, &progress);
+    }
+
+
+  output_table->AddColumn(source_array);
+  output_table->AddColumn(target_array);
+  output_table->AddColumn(value_array);
+
+  source_array->Delete();
+  target_array->Delete();
+  value_array->Delete();
+
+  return 1;
+}
+
diff --git a/Infovis/vtkAdjacencyMatrixToEdgeTable.h b/Infovis/vtkAdjacencyMatrixToEdgeTable.h
new file mode 100644
index 00000000000..12990d1fb92
--- /dev/null
+++ b/Infovis/vtkAdjacencyMatrixToEdgeTable.h
@@ -0,0 +1,87 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkAdjacencyMatrixToEdgeTable.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkAdjacencyMatrixToEdgeTable_h
+#define __vtkAdjacencyMatrixToEdgeTable_h
+
+#include "vtkTableAlgorithm.h"
+
+// .NAME vtkAdjacencyMatrixToEdgeTable
+
+// .SECTION Description
+// Treats a dense 2-way array of doubles as an adacency matrix and converts it into a
+// vtkTable suitable for use as an edge table with vtkTableToGraph.
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkAdjacencyMatrixToEdgeTable : public vtkTableAlgorithm
+{
+public:
+  static vtkAdjacencyMatrixToEdgeTable* New();
+  vtkTypeRevisionMacro(vtkAdjacencyMatrixToEdgeTable, vtkTableAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Specifies whether rows or columns become the "source" in the output edge table.
+  // 0 = rows, 1 = columns.
+  vtkGetMacro(SourceDimension, vtkIdType);
+  vtkSetMacro(SourceDimension, vtkIdType);
+
+  // Description:
+  // Controls the name of the output table column that contains edge weights.
+  vtkGetStringMacro(ValueArrayName);
+  vtkSetStringMacro(ValueArrayName);
+
+  // Description:
+  // Specifies the minimum number of adjacent edges to include for each source vertex.
+  vtkGetMacro(MinimumCount, vtkIdType);
+  vtkSetMacro(MinimumCount, vtkIdType);
+
+  // Description:
+  // Specifies a minimum threshold that an edge weight must exceed to be included in
+  // the output.
+  vtkGetMacro(MinimumThreshold, double);
+  vtkSetMacro(MinimumThreshold, double);
+
+protected:
+  vtkAdjacencyMatrixToEdgeTable();
+  ~vtkAdjacencyMatrixToEdgeTable();
+
+  int FillInputPortInformation(int, vtkInformation*);
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+  vtkIdType SourceDimension;
+  char* ValueArrayName;
+  vtkIdType MinimumCount;
+  double MinimumThreshold;
+
+private:
+  vtkAdjacencyMatrixToEdgeTable(const vtkAdjacencyMatrixToEdgeTable&); // Not implemented
+  void operator=(const vtkAdjacencyMatrixToEdgeTable&);   // Not implemented
+};
+
+#endif
+
diff --git a/Infovis/vtkArrayToTable.cxx b/Infovis/vtkArrayToTable.cxx
new file mode 100644
index 00000000000..27839aea960
--- /dev/null
+++ b/Infovis/vtkArrayToTable.cxx
@@ -0,0 +1,135 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkArrayToTable.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkArrayData.h"
+#include "vtkArrayToTable.h"
+#include "vtkDenseArray.h"
+#include "vtkDoubleArray.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkSparseArray.h"
+#include "vtkTable.h"
+
+#include <vtksys/ios/sstream>
+
+// ----------------------------------------------------------------------
+
+vtkCxxRevisionMacro(vtkArrayToTable, "1.1");
+vtkStandardNewMacro(vtkArrayToTable);
+
+// ----------------------------------------------------------------------
+
+vtkArrayToTable::vtkArrayToTable()
+{
+  this->SetNumberOfInputPorts(1);
+  this->SetNumberOfOutputPorts(1);
+}
+
+// ----------------------------------------------------------------------
+
+vtkArrayToTable::~vtkArrayToTable()
+{
+}
+
+// ----------------------------------------------------------------------
+
+void vtkArrayToTable::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+int vtkArrayToTable::FillInputPortInformation(int port, vtkInformation* info)
+{
+  switch(port)
+    {
+    case 0:
+      info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkArrayData");
+      return 1;
+    }
+
+  return 0;
+}
+
+// ----------------------------------------------------------------------
+
+int vtkArrayToTable::RequestData(
+  vtkInformation*, 
+  vtkInformationVector** inputVector, 
+  vtkInformationVector* outputVector)
+{
+  vtkArrayData* const input = vtkArrayData::GetData(inputVector[0]);
+  vtkTable* const output = vtkTable::GetData(outputVector);
+
+  vtkTypedArray<double>* const array = vtkTypedArray<double>::SafeDownCast(input->GetArray());
+  if(!array)
+    {
+    vtkErrorMacro(<< "vtkArrayToTable requires vtkTypedArray<double> as input");
+    return 0;
+    }
+
+  if(array->GetExtents().GetDimensions() == 1)
+    {
+    const vtkArrayExtents extents = array->GetExtents();
+
+    vtkDoubleArray* const column = vtkDoubleArray::New();
+    column->SetNumberOfTuples(extents[0]);
+    column->SetName("0");
+    output->AddColumn(column);
+    column->Delete();
+
+    for(vtkIdType i = 0; i != extents[0]; ++i)
+      {
+      column->SetValue(i, array->GetValue(vtkArrayCoordinates(i)));
+      }
+    }
+  else if(array->GetExtents().GetDimensions() == 2)
+    {
+    const vtkArrayExtents extents = array->GetExtents();
+
+    for(vtkIdType j = 0; j != extents[1]; ++j)
+      {
+      vtkstd::ostringstream column_name;
+      column_name << j;
+        
+      vtkDoubleArray* const column = vtkDoubleArray::New();
+      column->SetNumberOfTuples(extents[0]);
+      column->SetName(column_name.str().c_str());
+
+      for(vtkIdType i = 0; i != extents[0]; ++i)
+        {
+        column->SetValue(i, array->GetValue(vtkArrayCoordinates(i, j)));
+        }
+
+      output->AddColumn(column);
+      column->Delete();
+      }
+    }
+  else
+    {
+    vtkErrorMacro(<< "vtkArrayToTable require an input array with 1 or 2 dimensions.");
+    return 0;
+    }
+
+  return 1;
+}
+
diff --git a/Infovis/vtkArrayToTable.h b/Infovis/vtkArrayToTable.h
new file mode 100644
index 00000000000..7f6cbbcda1f
--- /dev/null
+++ b/Infovis/vtkArrayToTable.h
@@ -0,0 +1,57 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkArrayToTable.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkArrayToTable_h
+#define __vtkArrayToTable_h
+
+#include "vtkTableAlgorithm.h"
+
+// .NAME vtkArrayToTable - Converts one- and two-dimensional vtkArrayData
+// objects to vtkTable
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkArrayToTable : public vtkTableAlgorithm
+{
+public:
+  static vtkArrayToTable* New();
+  vtkTypeRevisionMacro(vtkArrayToTable, vtkTableAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+protected:
+  vtkArrayToTable();
+  ~vtkArrayToTable();
+
+  int FillInputPortInformation(int, vtkInformation*);
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+private:
+  vtkArrayToTable(const vtkArrayToTable&); // Not implemented
+  void operator=(const vtkArrayToTable&);   // Not implemented
+};
+
+#endif
+
diff --git a/Infovis/vtkBoostLogWeighting.cxx b/Infovis/vtkBoostLogWeighting.cxx
new file mode 100644
index 00000000000..133f39599a9
--- /dev/null
+++ b/Infovis/vtkBoostLogWeighting.cxx
@@ -0,0 +1,88 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkBoostLogWeighting.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkArrayCoordinates.h"
+#include "vtkCommand.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkBoostLogWeighting.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkTypedArray.h"
+
+#include <boost/math/special_functions/log1p.hpp>
+#include <boost/version.hpp>
+#if BOOST_VERSION < 103400
+  #error "vtkBoostLogWeighting requires Boost 1.34.0 or later"
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// vtkBoostLogWeighting
+
+vtkCxxRevisionMacro(vtkBoostLogWeighting, "1.1");
+vtkStandardNewMacro(vtkBoostLogWeighting);
+
+vtkBoostLogWeighting::vtkBoostLogWeighting()
+{
+}
+
+vtkBoostLogWeighting::~vtkBoostLogWeighting()
+{
+}
+
+void vtkBoostLogWeighting::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+int vtkBoostLogWeighting::RequestData(
+  vtkInformation*, 
+  vtkInformationVector** inputVector, 
+  vtkInformationVector* outputVector)
+{
+  vtkArrayData* const input = vtkArrayData::GetData(inputVector[0]);
+  vtkArrayData* const output = vtkArrayData::GetData(outputVector);
+
+  if(vtkTypedArray<double>* const input_array = vtkTypedArray<double>::SafeDownCast(input->GetArray()))
+    {
+    vtkTypedArray<double>* const output_array = vtkTypedArray<double>::SafeDownCast(input_array->DeepCopy());
+    output->SetArray(output_array);
+    output_array->Delete();
+
+    const vtkIdType value_count = input_array->GetNonNullSize();
+    
+    for(vtkIdType i = 0; i != value_count; ++i)
+      {
+      output_array->SetValueN(i, boost::math::log1p(output_array->GetValueN(i)));
+
+      double progress = static_cast<double>(i) / static_cast<double>(value_count);
+      this->InvokeEvent(vtkCommand::ProgressEvent, &progress);
+      }
+    }
+  else
+    {
+    vtkErrorMacro(<< "Unsupported input array type");
+    return 0;
+    }
+  
+  return 1;
+}
+
diff --git a/Infovis/vtkBoostLogWeighting.h b/Infovis/vtkBoostLogWeighting.h
new file mode 100644
index 00000000000..24a04029153
--- /dev/null
+++ b/Infovis/vtkBoostLogWeighting.h
@@ -0,0 +1,56 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkBoostLogWeighting.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkBoostLogWeighting_h
+#define __vtkBoostLogWeighting_h
+
+#include "vtkArrayDataAlgorithm.h"
+#include "vtkSetGet.h"
+
+// .NAME vtkBoostLogWeighting - Given an arbitrary-dimension array of doubles,
+// replaces each value with the base-e log of (value + 1)
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkBoostLogWeighting : public vtkArrayDataAlgorithm
+{
+public:
+  static vtkBoostLogWeighting* New();
+  vtkTypeRevisionMacro(vtkBoostLogWeighting, vtkArrayDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+protected:
+  vtkBoostLogWeighting();
+  ~vtkBoostLogWeighting();
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+private:
+  vtkBoostLogWeighting(const vtkBoostLogWeighting&); // Not implemented
+  void operator=(const vtkBoostLogWeighting&);   // Not implemented
+};
+
+#endif
+
diff --git a/Infovis/vtkBoostRandomSparseArraySource.cxx b/Infovis/vtkBoostRandomSparseArraySource.cxx
new file mode 100644
index 00000000000..231678889a7
--- /dev/null
+++ b/Infovis/vtkBoostRandomSparseArraySource.cxx
@@ -0,0 +1,123 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkBoostRandomSparseArraySource.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkArrayCoordinateIterator.h"
+#include "vtkBoostRandomSparseArraySource.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkSparseArray.h"
+
+#include <boost/random.hpp>
+
+// ----------------------------------------------------------------------
+
+vtkCxxRevisionMacro(vtkBoostRandomSparseArraySource, "1.1");
+vtkStandardNewMacro(vtkBoostRandomSparseArraySource);
+
+// ----------------------------------------------------------------------
+
+vtkBoostRandomSparseArraySource::vtkBoostRandomSparseArraySource() :
+  Extents(2, 2),
+  ElementProbabilitySeed(123),
+  ElementProbability(0.5),
+  ElementValueSeed(456),
+  MinValue(0.0),
+  MaxValue(1.0)
+{
+  this->SetNumberOfInputPorts(0);
+  this->SetNumberOfOutputPorts(1);
+}
+
+// ----------------------------------------------------------------------
+
+vtkBoostRandomSparseArraySource::~vtkBoostRandomSparseArraySource()
+{
+}
+
+// ----------------------------------------------------------------------
+
+void vtkBoostRandomSparseArraySource::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "Extents: " << this->Extents << endl;
+  os << indent << "ElementProbabilitySeed: " << this->ElementProbabilitySeed << endl;
+  os << indent << "ElementProbability: " << this->ElementProbability << endl;
+  os << indent << "ElementValueSeed: " << this->ElementValueSeed << endl;
+  os << indent << "MinValue: " << this->MinValue << endl;
+  os << indent << "MaxValue: " << this->MaxValue << endl;
+}
+
+void vtkBoostRandomSparseArraySource::SetExtents(const vtkArrayExtents& extents)
+{
+  if(extents == this->Extents)
+    return;
+
+  this->Extents = extents;
+  this->Modified();
+}
+
+vtkArrayExtents vtkBoostRandomSparseArraySource::GetExtents()
+{
+  return this->Extents;
+}
+
+// ----------------------------------------------------------------------
+
+int vtkBoostRandomSparseArraySource::RequestData(
+  vtkInformation*, 
+  vtkInformationVector**, 
+  vtkInformationVector* outputVector)
+{
+  boost::mt19937 pattern_generator(static_cast<boost::uint32_t>(this->ElementProbabilitySeed));
+  boost::bernoulli_distribution<> pattern_distribution(this->ElementProbability);
+  boost::variate_generator<boost::mt19937&, boost::bernoulli_distribution<> > pattern(pattern_generator, pattern_distribution);
+
+  boost::mt19937 value_generator(static_cast<boost::uint32_t>(this->ElementValueSeed));
+  boost::uniform_real<> value_distribution(this->MinValue, this->MaxValue);
+  boost::variate_generator<boost::mt19937&, boost::uniform_real<> > values(value_generator, value_distribution);
+
+  vtkSparseArray<double>* const array = vtkSparseArray<double>::New();
+  array->Resize(this->Extents);
+
+  vtkSmartPointer<vtkArrayCoordinateIterator> iterator = vtkSmartPointer<vtkArrayCoordinateIterator>::New();
+  iterator->SetExtents(this->Extents);
+  while(iterator->HasNext())
+    {
+    vtkArrayCoordinates coordinates = iterator->Next();
+
+    // Although it seems wasteful, we calculate a value for every element in the array
+    // so the results stay consistent as the ElementProbability varies
+    const double value = values();
+    if(pattern())
+      {
+      array->AddValue(coordinates, value);
+      }
+    }
+
+  vtkArrayData* const output = vtkArrayData::GetData(outputVector);
+  output->SetArray(array);
+  array->Delete();
+
+  return 1;
+}
+
diff --git a/Infovis/vtkBoostRandomSparseArraySource.h b/Infovis/vtkBoostRandomSparseArraySource.h
new file mode 100644
index 00000000000..07d050a9c9e
--- /dev/null
+++ b/Infovis/vtkBoostRandomSparseArraySource.h
@@ -0,0 +1,99 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkBoostRandomSparseArraySource.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkBoostRandomSparseArraySource_h
+#define __vtkBoostRandomSparseArraySource_h
+
+#include "vtkArrayDataAlgorithm.h"
+#include "vtkArrayExtents.h"
+
+// .NAME vtkBoostRandomSparseArraySource - generates a sparse N-way array containing random values.
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkBoostRandomSparseArraySource : public vtkArrayDataAlgorithm
+{
+public:
+  static vtkBoostRandomSparseArraySource* New();
+  vtkTypeRevisionMacro(vtkBoostRandomSparseArraySource, vtkArrayDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Sets the extents (dimensionality and size) of the output array
+  void SetExtents(const vtkArrayExtents&);
+  
+  // Description:
+  // Returns the extents (dimensionality and size) of the output array
+  vtkArrayExtents GetExtents();
+
+  // Description:
+  // Stores a random-number-seed for determining which elements within
+  // the output matrix will have non-zero values 
+  vtkGetMacro(ElementProbabilitySeed, vtkTypeUInt32);
+  vtkSetMacro(ElementProbabilitySeed, vtkTypeUInt32);
+
+  // Description:
+  // Stores the probability (in the range [0, 1]) that an element within
+  // the output matrix will have a non-zero value
+  vtkGetMacro(ElementProbability, double);
+  vtkSetMacro(ElementProbability, double);
+
+  // Description:
+  // Stores a random-number-seed for computing random element values
+  vtkGetMacro(ElementValueSeed, vtkTypeUInt32);
+  vtkSetMacro(ElementValueSeed, vtkTypeUInt32);
+
+  // Description:
+  // Stores the minimum value of any element
+  vtkGetMacro(MinValue, double);
+  vtkSetMacro(MinValue, double);
+
+  // Description:
+  // Stores the maximum value of any element
+  vtkGetMacro(MaxValue, double);
+  vtkSetMacro(MaxValue, double);
+
+protected:
+  vtkBoostRandomSparseArraySource();
+  ~vtkBoostRandomSparseArraySource();
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+private:
+  vtkBoostRandomSparseArraySource(const vtkBoostRandomSparseArraySource&); // Not implemented
+  void operator=(const vtkBoostRandomSparseArraySource&);   // Not implemented
+
+  vtkArrayExtents Extents;
+
+  vtkTypeUInt32 ElementProbabilitySeed;
+  double ElementProbability;
+
+  vtkTypeUInt32 ElementValueSeed;
+  double MinValue;
+  double MaxValue;
+};
+
+#endif
+
diff --git a/Infovis/vtkCosineSimilarity.cxx b/Infovis/vtkCosineSimilarity.cxx
new file mode 100644
index 00000000000..cd11c3fd972
--- /dev/null
+++ b/Infovis/vtkCosineSimilarity.cxx
@@ -0,0 +1,223 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkCosineSimilarity.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkArrayData.h"
+#include "vtkCommand.h"
+#include "vtkCosineSimilarity.h"
+#include "vtkDenseArray.h"
+#include "vtkDoubleArray.h"
+#include "vtkIdTypeArray.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkTable.h"
+
+#include <vtksys/stl/algorithm>
+#include <vtkstd/map>
+
+// threshold_multimap
+// This strange little fellow is used by the vtkCosineSimilarity
+// implementation.  It provides the interface
+// of a vtkstd::multimap, but it enforces several constraints on its contents:
+//
+// There is an upper-limit on the number of values stored in the container.
+// There is a lower threshold on key-values stored in the container.
+// The key threshold can be overridden by specifying a lower-limit on the
+// number of values stored in the container.
+
+template<typename KeyT, typename ValueT>
+class threshold_multimap :
+  public vtkstd::multimap<KeyT, ValueT, vtkstd::less<KeyT> >
+{
+  typedef vtkstd::multimap<KeyT, ValueT, vtkstd::less<KeyT> > container_t;
+
+public:
+  threshold_multimap(KeyT minimum_threshold, size_t minimum_count, size_t maximum_count) :
+    MinimumThreshold(minimum_threshold),
+    MinimumCount(vtkstd::max(static_cast<size_t>(0), minimum_count)),
+    MaximumCount(vtkstd::max(static_cast<size_t>(0), maximum_count))
+  {
+  }
+
+  void insert(const typename container_t::value_type& value)
+  {
+    // Insert the value into the container ...
+    container_t::insert(value);
+
+    // Prune small values down to our minimum size ...
+    while((this->size() > this->MinimumCount) && (this->begin()->first < this->MinimumThreshold))
+      this->erase(this->begin());
+      
+    // Prune small values down to our maximum size ...
+    while(this->size() > this->MaximumCount)
+      this->erase(this->begin());
+  }
+
+private:
+  typename container_t::iterator insert(typename container_t::iterator where, const typename container_t::value_type& value);
+  template<class InIt>
+  void insert(InIt first, InIt last);
+
+  const KeyT MinimumThreshold;
+  const size_t MinimumCount;
+  const size_t MaximumCount;
+};
+
+// ----------------------------------------------------------------------
+
+vtkCxxRevisionMacro(vtkCosineSimilarity, "1.1");
+vtkStandardNewMacro(vtkCosineSimilarity);
+
+// ----------------------------------------------------------------------
+
+vtkCosineSimilarity::vtkCosineSimilarity() :
+  VectorDimension(1),
+  MinimumThreshold(1),
+  MinimumCount(1),
+  MaximumCount(10)
+{
+  this->SetNumberOfInputPorts(1);
+  this->SetNumberOfOutputPorts(1);
+}
+
+// ----------------------------------------------------------------------
+
+vtkCosineSimilarity::~vtkCosineSimilarity()
+{
+}
+
+// ----------------------------------------------------------------------
+
+void vtkCosineSimilarity::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "VectorDimension: " << this->VectorDimension << endl;
+  os << indent << "MinimumThreshold: " << this->MinimumThreshold << endl;
+  os << indent << "MinimumCount: " << this->MinimumCount << endl;
+  os << indent << "MaximumCount: " << this->MaximumCount << endl;
+}
+
+int vtkCosineSimilarity::FillInputPortInformation(int port, vtkInformation* info)
+{
+  switch(port)
+    {
+    case 0:
+      info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkArrayData");
+      return 1;
+    }
+
+  return 0;
+}
+
+// ----------------------------------------------------------------------
+
+int vtkCosineSimilarity::RequestData(
+  vtkInformation*, 
+  vtkInformationVector** inputVector, 
+  vtkInformationVector* outputVector)
+{
+  // Get input arrays ...
+  vtkArrayData* const input = vtkArrayData::GetData(inputVector[0]);
+  vtkDenseArray<double>* const input_array = vtkDenseArray<double>::SafeDownCast(input->GetArray());
+  if(!input_array)
+    {
+    vtkErrorMacro(<< "vtkCosineSimilarity requires a vtkDenseArray<double> as input.");
+    return 0;
+    }
+  if(input_array->GetExtents().GetDimensions() != 2)
+    {
+    vtkErrorMacro(<< "vtkCosineSimilarity requires a matrix as input.");
+    return 0;
+    }
+
+  // Get output arrays ...
+  vtkTable* const output = vtkTable::GetData(outputVector);
+ 
+  vtkIdTypeArray* const source_array = vtkIdTypeArray::New();
+  source_array->SetName("source");
+  
+  vtkIdTypeArray* const target_array = vtkIdTypeArray::New();
+  target_array->SetName("target");
+
+  vtkDoubleArray* const similarity_array = vtkDoubleArray::New();
+  similarity_array->SetName("similarity");
+
+  vtkArrayCoordinates coordinates1(0, 0);
+  vtkArrayCoordinates coordinates2(0, 0);
+
+  // Okay let outside world know that I'm starting
+  double progress = 0;
+  this->InvokeEvent(vtkCommand::ProgressEvent, &progress);
+
+  const int vector_dimension = vtkstd::min(1, vtkstd::max(0, this->VectorDimension));
+  const int component_dimension = 1 - vector_dimension;
+
+  const vtkIdType vector_count = input_array->GetExtents()[vector_dimension];
+  const vtkIdType component_count = input_array->GetExtents()[component_dimension];
+
+  // for each pair of vectors in the matrix ...
+  for(vtkIdType vector1 = 0; vector1 < vector_count; ++vector1)
+    {
+    coordinates1[vector_dimension] = vector1;
+
+    // Keep a sorted list of similarities as-we-go ...
+    typedef threshold_multimap<double, vtkIdType> similarities_t;
+    similarities_t similarities(this->MinimumThreshold, this->MinimumCount, this->MaximumCount);
+    for(vtkIdType vector2 = vector1 + 1; vector2 < vector_count; ++vector2)
+      {
+      coordinates2[vector_dimension] = vector2;
+
+      // Compute the dot-product of the two columns ...
+      double dot_product = 0.0;
+      for(vtkIdType component = 0; component < component_count; ++component)
+        {
+        coordinates1[component_dimension] = component;
+        coordinates2[component_dimension] = component;
+        dot_product += input_array->GetValue(coordinates1) * input_array->GetValue(coordinates2);
+        }
+
+      similarities.insert(vtkstd::make_pair(dot_product, vector2));
+      }
+      
+    // Now that we have our sorted list of similarities, store the results ...
+    for(similarities_t::const_iterator similarity = similarities.begin(); similarity != similarities.end(); ++similarity)
+      {
+      source_array->InsertNextValue(vector1);
+      target_array->InsertNextValue(similarity->second);
+      similarity_array->InsertNextValue(similarity->first);
+      }
+
+    progress = static_cast<double>(vector1) / static_cast<double>(vector_count);
+    this->InvokeEvent(vtkCommand::ProgressEvent, &progress);
+    }
+
+  output->AddColumn(source_array);
+  output->AddColumn(target_array);
+  output->AddColumn(similarity_array);
+
+  source_array->Delete();
+  target_array->Delete();
+  similarity_array->Delete();
+
+  return 1;
+}
+
diff --git a/Infovis/vtkCosineSimilarity.h b/Infovis/vtkCosineSimilarity.h
new file mode 100644
index 00000000000..af0e777c373
--- /dev/null
+++ b/Infovis/vtkCosineSimilarity.h
@@ -0,0 +1,90 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkCosineSimilarity.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkCosineSimilarity_h
+#define __vtkCosineSimilarity_h
+
+#include "vtkTableAlgorithm.h"
+
+// .NAME vtkCosineSimilarity
+
+// .SECTION Description
+// Treats a matrix as a collection of vectors and computes the cosine similarity
+// between each pair vectors, returning the results as an edge-table that
+// includes the index of each vector with their computed similarity.
+//
+// Note that the complexity of this filter is quadratic!
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkCosineSimilarity : public vtkTableAlgorithm
+{
+public:
+  static vtkCosineSimilarity* New();
+  vtkTypeRevisionMacro(vtkCosineSimilarity, vtkTableAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Controls whether to compute similarities for row-vectors or column-vectors.
+  // 0 = rows, 1 = columns.
+  vtkGetMacro(VectorDimension, int);
+  vtkSetMacro(VectorDimension, int);
+
+  // Description:
+  // Specifies a minimum threshold that a similarity must exceed to be included in
+  // the output.
+  vtkGetMacro(MinimumThreshold, double);
+  vtkSetMacro(MinimumThreshold, double);
+
+  // Description:
+  // Specifies a minimum number of edges to include for each vector.
+  vtkGetMacro(MinimumCount, int);
+  vtkSetMacro(MinimumCount, int);
+
+  // Description:
+  // Specifies a maximum number of edges to include for each vector.
+  vtkGetMacro(MaximumCount, int);
+  vtkSetMacro(MaximumCount, int);
+
+protected:
+  vtkCosineSimilarity();
+  ~vtkCosineSimilarity();
+
+  int FillInputPortInformation(int, vtkInformation*);
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+private:
+  vtkCosineSimilarity(const vtkCosineSimilarity&); // Not implemented
+  void operator=(const vtkCosineSimilarity&);   // Not implemented
+
+  int VectorDimension;
+  double MinimumThreshold;
+  int MinimumCount;
+  int MaximumCount;
+};
+
+#endif
+
diff --git a/Infovis/vtkDiagonalMatrixSource.cxx b/Infovis/vtkDiagonalMatrixSource.cxx
new file mode 100644
index 00000000000..076a9839192
--- /dev/null
+++ b/Infovis/vtkDiagonalMatrixSource.cxx
@@ -0,0 +1,153 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkDiagonalMatrixSource.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkDenseArray.h"
+#include "vtkDiagonalMatrixSource.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkSparseArray.h"
+
+// ----------------------------------------------------------------------
+
+vtkCxxRevisionMacro(vtkDiagonalMatrixSource, "1.1");
+vtkStandardNewMacro(vtkDiagonalMatrixSource);
+
+// ----------------------------------------------------------------------
+
+vtkDiagonalMatrixSource::vtkDiagonalMatrixSource() :
+  ArrayType(DENSE),
+  Extents(3),
+  Diagonal(1.0),
+  SuperDiagonal(0.0),
+  SubDiagonal(0.0)
+{
+  this->SetNumberOfInputPorts(0);
+  this->SetNumberOfOutputPorts(1);
+}
+
+// ----------------------------------------------------------------------
+
+vtkDiagonalMatrixSource::~vtkDiagonalMatrixSource()
+{
+}
+
+// ----------------------------------------------------------------------
+
+void vtkDiagonalMatrixSource::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "ArrayType: " << this->ArrayType << endl;
+  os << indent << "Extents: " << this->Extents << endl;
+  os << indent << "Diagonal: " << this->Diagonal << endl;
+  os << indent << "SuperDiagonal: " << this->SuperDiagonal << endl;
+  os << indent << "SubDiagonal: " << this->SubDiagonal << endl;
+}
+
+// ----------------------------------------------------------------------
+
+int vtkDiagonalMatrixSource::RequestData(
+  vtkInformation*, 
+  vtkInformationVector**, 
+  vtkInformationVector* outputVector)
+{
+  if(this->Extents < 1)
+    {
+    vtkErrorMacro(<< "Invalid matrix extents: " << this->Extents << "x" << this->Extents << " array is not supported.");
+    return 0;
+    }
+ 
+  vtkArray* array = 0;
+  switch(this->ArrayType)
+    {
+    case DENSE:
+      array = this->GenerateDenseArray();
+      break;
+    case SPARSE:
+      array = this->GenerateSparseArray();
+      break;
+    default:
+      vtkErrorMacro(<< "Invalid array type: " << this->ArrayType << ".");
+      return 0;
+    }
+    
+  vtkArrayData* const output = vtkArrayData::GetData(outputVector);
+  output->SetArray(array);
+  array->Delete();
+
+  return 1;
+}
+
+vtkArray* vtkDiagonalMatrixSource::GenerateDenseArray()
+{
+  vtkDenseArray<double>* const array = vtkDenseArray<double>::New();
+  array->Resize(vtkArrayExtents::Uniform(2, this->Extents));
+
+  array->Fill(0.0);
+
+  if(this->Diagonal != 0.0)
+    {
+    for(vtkIdType i = 0; i != this->Extents; ++i)
+      array->SetValue(vtkArrayCoordinates(i, i), this->Diagonal);
+    }
+
+  if(this->SuperDiagonal != 0.0)
+    {
+    for(vtkIdType i = 0; i + 1 != this->Extents; ++i)
+      array->SetValue(vtkArrayCoordinates(i, i+1), this->SuperDiagonal);
+    }
+
+  if(this->SubDiagonal != 0.0)
+    {
+    for(vtkIdType i = 0; i + 1 != this->Extents; ++i)
+      array->SetValue(vtkArrayCoordinates(i+1, i), this->SubDiagonal);
+    }
+
+  return array;
+}
+
+vtkArray* vtkDiagonalMatrixSource::GenerateSparseArray()
+{
+  vtkSparseArray<double>* const array = vtkSparseArray<double>::New();
+  array->Resize(vtkArrayExtents::Uniform(2, this->Extents));
+
+  if(this->Diagonal != 0.0)
+    {
+    for(vtkIdType i = 0; i != this->Extents; ++i)
+      array->AddValue(vtkArrayCoordinates(i, i), this->Diagonal);
+    }
+
+  if(this->SuperDiagonal != 0.0)
+    {
+    for(vtkIdType i = 0; i + 1 != this->Extents; ++i)
+      array->AddValue(vtkArrayCoordinates(i, i+1), this->SuperDiagonal);
+    }
+
+  if(this->SubDiagonal != 0.0)
+    {
+    for(vtkIdType i = 0; i + 1 != this->Extents; ++i)
+      array->AddValue(vtkArrayCoordinates(i+1, i), this->SubDiagonal);
+    }
+
+  return array;
+}
+
diff --git a/Infovis/vtkDiagonalMatrixSource.h b/Infovis/vtkDiagonalMatrixSource.h
new file mode 100644
index 00000000000..6f33880b186
--- /dev/null
+++ b/Infovis/vtkDiagonalMatrixSource.h
@@ -0,0 +1,97 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkDiagonalMatrixSource.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkDiagonalMatrixSource_h
+#define __vtkDiagonalMatrixSource_h
+
+#include "vtkArrayDataAlgorithm.h"
+#include "vtkArrayExtents.h"
+
+// .NAME vtkDiagonalMatrixSource - generates a sparse or dense square matrix
+// with user-specified values for the diagonal, superdiagonal, and subdiagonal.
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkDiagonalMatrixSource : public vtkArrayDataAlgorithm
+{
+public:
+  static vtkDiagonalMatrixSource* New();
+  vtkTypeRevisionMacro(vtkDiagonalMatrixSource, vtkArrayDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+//BTX
+  // Determines whether the output matrix will be dense or sparse
+  enum StorageType
+  {
+    DENSE,
+    SPARSE
+  };
+//ETX
+
+  vtkGetMacro(ArrayType, int);
+  vtkSetMacro(ArrayType, int);
+
+  // Description:
+  // Stores the extents of the output matrix (which is square)
+  vtkGetMacro(Extents, vtkIdType);
+  vtkSetMacro(Extents, vtkIdType);
+
+  // Description:
+  // Stores the value that will be assigned to diagonal elements (default: 1)
+  vtkGetMacro(Diagonal, double);
+  vtkSetMacro(Diagonal, double);
+
+  // Description:
+  // Stores the value that will be assigned to superdiagonal elements (default: 0)
+  vtkGetMacro(SuperDiagonal, double);
+  vtkSetMacro(SuperDiagonal, double);
+
+  // Description:
+  // Stores the value that will be assigned to subdiagonal elements (default: 0)
+  vtkGetMacro(SubDiagonal, double);
+  vtkSetMacro(SubDiagonal, double);
+
+protected:
+  vtkDiagonalMatrixSource();
+  ~vtkDiagonalMatrixSource();
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+private:
+  vtkDiagonalMatrixSource(const vtkDiagonalMatrixSource&); // Not implemented
+  void operator=(const vtkDiagonalMatrixSource&);   // Not implemented
+
+  vtkArray* GenerateDenseArray();
+  vtkArray* GenerateSparseArray();
+
+  int ArrayType;
+  vtkIdType Extents;
+  double Diagonal;
+  double SuperDiagonal;
+  double SubDiagonal;
+};
+
+#endif
+
diff --git a/Infovis/vtkExtractFactoredArray.cxx b/Infovis/vtkExtractFactoredArray.cxx
new file mode 100644
index 00000000000..93551568b89
--- /dev/null
+++ b/Infovis/vtkExtractFactoredArray.cxx
@@ -0,0 +1,84 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkExtractFactoredArray.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkArrayData.h"
+#include "vtkCommand.h"
+#include "vtkFactoredArrayData.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkExtractFactoredArray.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// vtkExtractFactoredArray
+
+vtkCxxRevisionMacro(vtkExtractFactoredArray, "1.1");
+vtkStandardNewMacro(vtkExtractFactoredArray);
+
+vtkExtractFactoredArray::vtkExtractFactoredArray() :
+  Index(0)
+{
+  this->SetNumberOfInputPorts(1);
+  this->SetNumberOfOutputPorts(1);
+}
+
+vtkExtractFactoredArray::~vtkExtractFactoredArray()
+{
+}
+
+void vtkExtractFactoredArray::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "Index: " << this->Index << endl;
+}
+
+int vtkExtractFactoredArray::FillInputPortInformation(int port, vtkInformation* info)
+{
+  switch(port)
+    {
+    case 0:
+      info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkFactoredArrayData");
+      return 1;
+    }
+
+  return 0;
+}
+
+int vtkExtractFactoredArray::RequestData(
+  vtkInformation*, 
+  vtkInformationVector** inputVector, 
+  vtkInformationVector* outputVector)
+{
+  vtkFactoredArrayData* const input = vtkFactoredArrayData::GetData(inputVector[0]);
+
+  if(this->Index < 0 || this->Index >= input->GetNumberOfArrays())
+    {
+    vtkErrorMacro(<< "Array index " << this->Index << " out-of-range for vtkFactoredArrayData containing " << input->GetNumberOfArrays() << " arrays.");
+    return 0;
+    }
+
+  vtkArrayData* const output = vtkArrayData::GetData(outputVector);
+  output->SetArray(input->GetArray(this->Index));
+
+  return 1;
+}
+
diff --git a/Infovis/vtkExtractFactoredArray.h b/Infovis/vtkExtractFactoredArray.h
new file mode 100644
index 00000000000..96728b662c8
--- /dev/null
+++ b/Infovis/vtkExtractFactoredArray.h
@@ -0,0 +1,65 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkExtractFactoredArray.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkExtractFactoredArray_h
+#define __vtkExtractFactoredArray_h
+
+#include "vtkArrayDataAlgorithm.h"
+#include "vtkSetGet.h"
+
+// .NAME vtkExtractFactoredArray - Extracts the Nth array stored in a
+// vtkFactoredArrayData object into a pipeline array data object.
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkExtractFactoredArray : public vtkArrayDataAlgorithm
+{
+public:
+  static vtkExtractFactoredArray* New();
+  vtkTypeRevisionMacro(vtkExtractFactoredArray, vtkArrayDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Controls which array will be extracted.
+  vtkGetMacro(Index, vtkIdType);
+  vtkSetMacro(Index, vtkIdType);
+
+protected:
+  vtkExtractFactoredArray();
+  ~vtkExtractFactoredArray();
+
+  int FillInputPortInformation(int port, vtkInformation* info);
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+private:
+  vtkExtractFactoredArray(const vtkExtractFactoredArray&); // Not implemented
+  void operator=(const vtkExtractFactoredArray&);   // Not implemented
+
+  vtkIdType Index;
+};
+
+#endif
+
diff --git a/Infovis/vtkMatricizeArray.cxx b/Infovis/vtkMatricizeArray.cxx
new file mode 100644
index 00000000000..56d73046566
--- /dev/null
+++ b/Infovis/vtkMatricizeArray.cxx
@@ -0,0 +1,126 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkMatricizeArray.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkCommand.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkMatricizeArray.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkSparseArray.h"
+
+#include <vtksys/stl/numeric>
+
+///////////////////////////////////////////////////////////////////////////////
+// vtkMatricizeArray
+
+vtkCxxRevisionMacro(vtkMatricizeArray, "1.1");
+vtkStandardNewMacro(vtkMatricizeArray);
+
+vtkMatricizeArray::vtkMatricizeArray() :
+  SliceDimension(0)
+{
+}
+
+vtkMatricizeArray::~vtkMatricizeArray()
+{
+}
+
+void vtkMatricizeArray::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "SliceDimension: " << this->SliceDimension << endl;
+}
+
+int vtkMatricizeArray::RequestData(
+  vtkInformation*, 
+  vtkInformationVector** inputVector, 
+  vtkInformationVector* outputVector)
+{
+  vtkArrayData* const input = vtkArrayData::GetData(inputVector[0]);
+  vtkSparseArray<double>* const input_array = vtkSparseArray<double>::SafeDownCast(input->GetArray());
+  if(!input_array)
+    {
+    vtkErrorMacro(<< "vtkMatricizeArray requires a vtkSparseArray<double> as input.");
+    return 0;
+    }
+
+  if(this->SliceDimension < 0 || this->SliceDimension >= input_array->GetDimensions())
+    {
+    vtkErrorMacro(<< "Slice dimension " << this->SliceDimension << " out-of-range for array with " << input_array->GetDimensions() << " dimensions.");
+    return 0;
+    }
+
+  vtkSparseArray<double>* const output_array = vtkSparseArray<double>::New();
+
+  // Compute the extents of the output array ...
+  const vtkArrayExtents input_extents = input_array->GetExtents();
+  vtkArrayExtents output_extents(0, 0);
+  output_extents[0] = input_extents[this->SliceDimension];
+  output_extents[1] = input_extents.GetSize() / input_extents[this->SliceDimension];
+  output_array->Resize(output_extents);
+
+  // "Map" every non-null element in the input array to its position in the output array.
+  // Indices in the slice dimension map directly to the row index in the output.
+  // The remaining coordinates are multiplied by a "stride" value for each dimension and
+  // the results are summed to compute the output column index.
+  //
+  // Setting the slice-dimension stride to zero simplifies computation of column coordinates
+  // later-on and eliminate an inner-loop comparison.
+  vtkstd::vector<vtkIdType> strides(input_array->GetDimensions());
+  for(vtkIdType i = input_array->GetDimensions() - 1, stride = 1; i >= 0; --i)
+    {
+    if(i == this->SliceDimension)
+      {
+      strides[i] = 0;
+      }
+    else
+      {
+      strides[i] = stride;
+      stride *= input_extents[i];
+      }
+    }
+    
+  vtkstd::vector<vtkIdType> temp(input_array->GetDimensions());
+
+  vtkArrayCoordinates coordinates;
+  vtkArrayCoordinates new_coordinates(0, 0);
+  const vtkIdType element_count = input_array->GetNonNullSize();
+  for(vtkIdType n = 0; n != element_count; ++n)
+    {
+    input_array->GetCoordinatesN(n, coordinates);
+
+    new_coordinates[0] = coordinates[this->SliceDimension];
+
+    for(vtkIdType i = 0; i != coordinates.GetDimensions(); ++i)
+      temp[i] = coordinates[i] * strides[i];
+    new_coordinates[1] = vtkstd::accumulate(temp.begin(), temp.end(), 0);
+
+    output_array->AddValue(new_coordinates, input_array->GetValueN(n));
+    }
+
+  vtkArrayData* const output = vtkArrayData::GetData(outputVector);
+  output->SetArray(output_array);
+  output_array->Delete();
+
+  return 1;
+}
+
diff --git a/Infovis/vtkMatricizeArray.h b/Infovis/vtkMatricizeArray.h
new file mode 100644
index 00000000000..927e37e66df
--- /dev/null
+++ b/Infovis/vtkMatricizeArray.h
@@ -0,0 +1,77 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkMatricizeArray.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkMatricizeArray_h
+#define __vtkMatricizeArray_h
+
+#include "vtkArrayDataAlgorithm.h"
+#include "vtkSetGet.h"
+
+class vtkArrayExtents;
+
+// .NAME vtkMatricizeArray - Convert an array of arbitrary dimensions to a
+// matrix.
+
+// .SECTION Description
+// Given a sparse input array of arbitrary dimension, creates a sparse output
+// matrix (vtkSparseArray<double>) where each column is a slice along an
+// arbitrary dimension from the source.
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkMatricizeArray : public vtkArrayDataAlgorithm
+{
+public:
+  static vtkMatricizeArray* New();
+  vtkTypeRevisionMacro(vtkMatricizeArray, vtkArrayDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Returns the 0-numbered dimension that will be mapped to columns in the output
+  vtkGetMacro(SliceDimension, vtkIdType);
+  
+  // Description:
+  // Sets the 0-numbered dimension that will be mapped to columns in the output
+  vtkSetMacro(SliceDimension, vtkIdType);
+
+protected:
+  vtkMatricizeArray();
+  ~vtkMatricizeArray();
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+private:
+  vtkMatricizeArray(const vtkMatricizeArray&); // Not implemented
+  void operator=(const vtkMatricizeArray&);   // Not implemented
+
+//BTX
+  class Generator;
+//ETX
+
+  vtkIdType SliceDimension;
+};
+
+#endif
+
diff --git a/Infovis/vtkMatrixColumnNorm.cxx b/Infovis/vtkMatrixColumnNorm.cxx
new file mode 100644
index 00000000000..142e77bb448
--- /dev/null
+++ b/Infovis/vtkMatrixColumnNorm.cxx
@@ -0,0 +1,110 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkMatrixColumnNorm.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkCommand.h"
+#include "vtkDenseArray.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkMatrixColumnNorm.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// vtkMatrixColumnNorm
+
+vtkCxxRevisionMacro(vtkMatrixColumnNorm, "1.1");
+vtkStandardNewMacro(vtkMatrixColumnNorm);
+
+vtkMatrixColumnNorm::vtkMatrixColumnNorm() :
+  L(2)
+{
+}
+
+vtkMatrixColumnNorm::~vtkMatrixColumnNorm()
+{
+}
+
+void vtkMatrixColumnNorm::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "L: " << this->L << endl;
+}
+
+void vtkMatrixColumnNorm::SetL(int value)
+{
+  if(value < 1)
+    {
+    vtkErrorMacro(<< "Cannot compute vector norm for L < 1");
+    return;
+    }
+  
+  if(this->L == value)
+    return;
+
+  this->L = value;
+  this->Modified();
+}
+
+int vtkMatrixColumnNorm::RequestData(
+  vtkInformation*, 
+  vtkInformationVector** inputVector, 
+  vtkInformationVector* outputVector)
+{
+  vtkArrayData* const input = vtkArrayData::GetData(inputVector[0]);
+  vtkArrayData* const output = vtkArrayData::GetData(outputVector);
+
+  vtkDenseArray<double>* const output_array = vtkDenseArray<double>::New();
+  output->SetArray(output_array);
+  output_array->Delete();
+
+  vtkTypedArray<double>* const input_array = vtkTypedArray<double>::SafeDownCast(input->GetArray());
+  if(!input_array)
+    {
+    vtkErrorMacro(<< "vtkMatrixColumnNorm requires a vtkTypedArray<double> input array.");
+    return 0;
+    }
+  if(input_array->GetDimensions() != 2)
+    {
+    vtkErrorMacro(<< "vtkMatrixColumnNorm requires an input matrix.");
+    return 0;
+    }
+
+  const vtkArrayExtents input_extents = input_array->GetExtents();
+
+  output_array->Resize(vtkArrayExtents(input_extents[1]));
+  output_array->Fill(0.0);
+
+  vtkArrayCoordinates coordinates;
+  const vtkIdType element_count = input_array->GetNonNullSize();
+  for(vtkIdType n = 0; n != element_count; ++n)
+    {
+    input_array->GetCoordinatesN(n, coordinates);
+    (*output_array)[vtkArrayCoordinates(coordinates[1])] += pow(input_array->GetValueN(n), this->L);
+    }
+
+  for(vtkIdType i = 0; i != input_extents[1]; ++i)
+    {
+    (*output_array)[vtkArrayCoordinates(i)] = pow((*output_array)[vtkArrayCoordinates(i)], 1.0 / this->L);
+    }
+
+  return 1;
+}
+
diff --git a/Infovis/vtkMatrixColumnNorm.h b/Infovis/vtkMatrixColumnNorm.h
new file mode 100644
index 00000000000..48718e4edeb
--- /dev/null
+++ b/Infovis/vtkMatrixColumnNorm.h
@@ -0,0 +1,64 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkMatrixColumnNorm.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// .NAME vtkMatrixColumnNorm - given a sparse input matrix (vtkSparseArray<double>),
+// computes the L-norm for each column, storing the results in a dense output vector
+// (vtkDenseArray<double>).
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+#ifndef __vtkMatrixColumnNorm_h
+#define __vtkMatrixColumnNorm_h
+
+#include "vtkArrayDataAlgorithm.h"
+#include "vtkSetGet.h"
+
+class VTK_INFOVIS_EXPORT vtkMatrixColumnNorm : public vtkArrayDataAlgorithm
+{
+public:
+  static vtkMatrixColumnNorm* New();
+  vtkTypeRevisionMacro(vtkMatrixColumnNorm, vtkArrayDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Controls the L-value.  Default: 2
+  vtkGetMacro(L, int);
+  void SetL(int value);
+
+protected:
+  vtkMatrixColumnNorm();
+  ~vtkMatrixColumnNorm();
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+private:
+  vtkMatrixColumnNorm(const vtkMatrixColumnNorm&); // Not implemented
+  void operator=(const vtkMatrixColumnNorm&);   // Not implemented
+
+  int L;
+};
+
+#endif
+
diff --git a/Infovis/vtkNormalizeMatrixVectors.cxx b/Infovis/vtkNormalizeMatrixVectors.cxx
new file mode 100644
index 00000000000..780476da7d8
--- /dev/null
+++ b/Infovis/vtkNormalizeMatrixVectors.cxx
@@ -0,0 +1,108 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkNormalizeMatrixVectors.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkArrayCoordinates.h"
+#include "vtkCommand.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkNormalizeMatrixVectors.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkTypedArray.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// vtkNormalizeMatrixVectors
+
+vtkCxxRevisionMacro(vtkNormalizeMatrixVectors, "1.1");
+vtkStandardNewMacro(vtkNormalizeMatrixVectors);
+
+vtkNormalizeMatrixVectors::vtkNormalizeMatrixVectors() :
+  VectorDimension(1)
+{
+}
+
+vtkNormalizeMatrixVectors::~vtkNormalizeMatrixVectors()
+{
+}
+
+void vtkNormalizeMatrixVectors::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "VectorDimension: " << this->VectorDimension << endl;
+}
+
+int vtkNormalizeMatrixVectors::RequestData(
+  vtkInformation*, 
+  vtkInformationVector** inputVector, 
+  vtkInformationVector* outputVector)
+{
+  vtkArrayData* const input = vtkArrayData::GetData(inputVector[0]);
+  vtkArrayData* const output = vtkArrayData::GetData(outputVector);
+
+  int vector_dimension = vtkstd::min(1, vtkstd::max(0, this->VectorDimension));
+
+  vtkTypedArray<double>* const input_array = vtkTypedArray<double>::SafeDownCast(input->GetArray());
+  if(!input_array)
+    {
+    vtkErrorMacro(<< "vtkNormalizeMatrixVectors requires a vtkTypedArray<double> as input.");
+    return 0;
+    }
+  if(input_array->GetDimensions() != 2)
+    {
+    vtkErrorMacro(<< "vtkNormalizeMatrixVectors requires a matrix as input.");
+    return 0;
+    }
+
+  vtkTypedArray<double>* const output_array = vtkTypedArray<double>::SafeDownCast(input_array->DeepCopy());
+  output->SetArray(output_array);
+  output_array->Delete();
+
+  const vtkIdType vector_count = input_array->GetExtents()[vector_dimension];
+  const vtkIdType value_count = input_array->GetNonNullSize();
+  
+  // Create temporary storage for computed vector weights ...
+  vtkstd::vector<double> weight(vector_count, 0.0);
+
+  // Store the sum of the squares of each vector value ...
+  vtkArrayCoordinates coordinates;
+  for(vtkIdType n = 0; n != value_count; ++n)
+    {
+    output_array->GetCoordinatesN(n, coordinates);
+    weight[coordinates[vector_dimension]] += pow(output_array->GetValueN(n), 2);
+    }
+
+  // Convert the sums into weights, avoiding divide-by-zero ...
+  for(vtkIdType i = 0; i != vector_count; ++i)
+    {
+    const double length = sqrt(weight[i]);
+    weight[i] = length ? 1.0 / length : 0.0;
+    }
+
+  // Apply the weights to each vector ...
+  for(vtkIdType n = 0; n != value_count; ++n)
+    {
+    output_array->GetCoordinatesN(n, coordinates);
+    output_array->SetValueN(n, output_array->GetValueN(n) * weight[coordinates[vector_dimension]]);
+    }
+  
+  return 1;
+}
+
diff --git a/Infovis/vtkNormalizeMatrixVectors.h b/Infovis/vtkNormalizeMatrixVectors.h
new file mode 100644
index 00000000000..51bcc6e0ab5
--- /dev/null
+++ b/Infovis/vtkNormalizeMatrixVectors.h
@@ -0,0 +1,63 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkNormalizeMatrixVectors.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkNormalizeMatrixVectors_h
+#define __vtkNormalizeMatrixVectors_h
+
+#include "vtkArrayDataAlgorithm.h"
+#include "vtkSetGet.h"
+
+// .NAME vtkNormalizeMatrixVectors - given a sparse input matrix, produces
+// a sparse output matrix with each vector normalized to unit length.
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkNormalizeMatrixVectors : public vtkArrayDataAlgorithm
+{
+public:
+  static vtkNormalizeMatrixVectors* New();
+  vtkTypeRevisionMacro(vtkNormalizeMatrixVectors, vtkArrayDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Controls whether to normalize row-vectors or column-vectors.  0 = rows, 1 = columns.
+  vtkGetMacro(VectorDimension, int);
+  vtkSetMacro(VectorDimension, int);
+
+protected:
+  vtkNormalizeMatrixVectors();
+  ~vtkNormalizeMatrixVectors();
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+  int VectorDimension;
+
+private:
+  vtkNormalizeMatrixVectors(const vtkNormalizeMatrixVectors&); // Not implemented
+  void operator=(const vtkNormalizeMatrixVectors&);   // Not implemented
+};
+
+#endif
+
diff --git a/Infovis/vtkTableToSparseArray.cxx b/Infovis/vtkTableToSparseArray.cxx
new file mode 100644
index 00000000000..34ccf28727e
--- /dev/null
+++ b/Infovis/vtkTableToSparseArray.cxx
@@ -0,0 +1,178 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkTableToSparseArray.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkDoubleArray.h"
+#include "vtkIdTypeArray.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkLongLongArray.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkSparseArray.h"
+#include "vtkStdString.h"
+#include "vtkStringArray.h"
+#include "vtkTable.h"
+#include "vtkTableToSparseArray.h"
+
+#include <vtksys/stl/algorithm>
+
+class vtkTableToSparseArray::implementation
+{
+public:
+  vtkstd::vector<vtkStdString> Coordinates;
+  vtkStdString Values;
+};
+
+// ----------------------------------------------------------------------
+
+vtkCxxRevisionMacro(vtkTableToSparseArray, "1.1");
+vtkStandardNewMacro(vtkTableToSparseArray);
+
+// ----------------------------------------------------------------------
+
+vtkTableToSparseArray::vtkTableToSparseArray() :
+  Implementation(new implementation())
+{
+  this->SetNumberOfInputPorts(1);
+  this->SetNumberOfOutputPorts(1);
+}
+
+// ----------------------------------------------------------------------
+
+vtkTableToSparseArray::~vtkTableToSparseArray()
+{
+  delete this->Implementation;
+}
+
+// ----------------------------------------------------------------------
+
+void vtkTableToSparseArray::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  for(vtkIdType i = 0; i != this->Implementation->Coordinates.size(); ++i)
+    os << indent << "CoordinateColumn: " << this->Implementation->Coordinates[i] << endl;
+  os << indent << "ValueColumn: " << this->Implementation->Values << endl;
+}
+
+void vtkTableToSparseArray::ClearCoordinateColumns()
+{
+  this->Implementation->Coordinates.clear();
+  this->Modified();
+}
+
+void vtkTableToSparseArray::AddCoordinateColumn(const char* name)
+{
+  if(!name)
+    {
+    vtkErrorMacro(<< "cannot add coordinate column with NULL name");
+    return;
+    }
+    
+  this->Implementation->Coordinates.push_back(name);
+  this->Modified();
+}
+
+void vtkTableToSparseArray::SetValueColumn(const char* name)
+{
+  if(!name)
+    {
+    vtkErrorMacro(<< "cannot set value column with NULL name");
+    return;
+    }
+
+  this->Implementation->Values = name;
+  this->Modified();
+}
+
+const char* vtkTableToSparseArray::GetValueColumn()
+{
+  return this->Implementation->Values.c_str();
+}
+
+int vtkTableToSparseArray::FillInputPortInformation(int port, vtkInformation* info)
+{
+  switch(port)
+    {
+    case 0:
+      info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable");
+      return 1;
+    }
+
+  return 0;
+}
+
+// ----------------------------------------------------------------------
+
+int vtkTableToSparseArray::RequestData(
+  vtkInformation*, 
+  vtkInformationVector** inputVector, 
+  vtkInformationVector* outputVector)
+{
+  vtkTable* const table = vtkTable::GetData(inputVector[0]);
+
+  vtkstd::vector<vtkAbstractArray*> coordinates(this->Implementation->Coordinates.size());
+  for(vtkIdType i = 0; i != this->Implementation->Coordinates.size(); ++i)
+    {
+    coordinates[i] = table->GetColumnByName(this->Implementation->Coordinates[i].c_str());
+    if(!coordinates[i])
+      {
+      vtkErrorMacro(<< "missing coordinate array: " << this->Implementation->Coordinates[i].c_str());
+      }
+    }
+
+  if(vtkstd::count(coordinates.begin(), coordinates.end(), static_cast<vtkAbstractArray*>(0)))
+    {
+    return 0;
+    }
+  
+  vtkAbstractArray* const values = table->GetColumnByName(this->Implementation->Values.c_str());
+  if(!values)
+    {
+    vtkErrorMacro(<< "missing value array: " << this->Implementation->Values.c_str());
+    return 0;
+    }
+
+  vtkSparseArray<double>* const array = vtkSparseArray<double>::New();
+  array->Resize(vtkArrayExtents::Uniform(coordinates.size(), 0));
+
+  for(vtkIdType i = 0; i != coordinates.size(); ++i)
+    array->SetDimensionLabel(i, coordinates[i]->GetName());
+
+  vtkArrayCoordinates output_coordinates;
+  output_coordinates.SetDimensions(coordinates.size());
+  for(vtkIdType i = 0; i != table->GetNumberOfRows(); ++i)
+    {
+    for(vtkIdType j = 0; j != coordinates.size(); ++j)
+      {
+      output_coordinates[j] = coordinates[j]->GetVariantValue(i).ToInt();
+      }
+    array->AddValue(output_coordinates, values->GetVariantValue(i).ToDouble());
+    }
+
+  array->ResizeToContents();
+
+  vtkArrayData* const output = vtkArrayData::GetData(outputVector);
+  output->SetArray(array);
+  array->Delete();
+
+  return 1;
+}
+
diff --git a/Infovis/vtkTableToSparseArray.h b/Infovis/vtkTableToSparseArray.h
new file mode 100644
index 00000000000..d5fb172efc6
--- /dev/null
+++ b/Infovis/vtkTableToSparseArray.h
@@ -0,0 +1,82 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkTableToSparseArray.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkTableToSparseArray_h
+#define __vtkTableToSparseArray_h
+
+#include "vtkArrayDataAlgorithm.h"
+#include "vtkArrayExtents.h"
+
+// .NAME vtkTableToSparseArray - converts a vtkTable into a sparse array.
+//
+// .SECTION Description
+// Converts a vtkTable into a sparse array.  Use AddCoordinateColumn() to
+// designate one-to-many table columns that contain coordinates for each
+// array value, and SetValueColumn() to designate the table column that 
+// contains array values.
+//
+// Thus, the number of dimensions in the output array will equal the number
+// of calls to AddCoordinateColumn().
+//
+// The coordinate columns will also be used to populate dimension labels
+// in the output array.
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkTableToSparseArray : public vtkArrayDataAlgorithm
+{
+public:
+  static vtkTableToSparseArray* New();
+  vtkTypeRevisionMacro(vtkTableToSparseArray, vtkArrayDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  void ClearCoordinateColumns();
+  void AddCoordinateColumn(const char* name);
+
+  void SetValueColumn(const char* name);
+  const char* GetValueColumn();
+
+protected:
+  vtkTableToSparseArray();
+  ~vtkTableToSparseArray();
+
+  int FillInputPortInformation(int, vtkInformation*);
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+private:
+  vtkTableToSparseArray(const vtkTableToSparseArray&); // Not implemented
+  void operator=(const vtkTableToSparseArray&);   // Not implemented
+
+//BTX
+  class implementation;
+  implementation* const Implementation;
+
+  class Generator;
+//ETX
+};
+
+#endif
+
diff --git a/Infovis/vtkTransposeMatrix.cxx b/Infovis/vtkTransposeMatrix.cxx
new file mode 100644
index 00000000000..58309bc6ad5
--- /dev/null
+++ b/Infovis/vtkTransposeMatrix.cxx
@@ -0,0 +1,118 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkTransposeMatrix.cxx
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkCommand.h"
+#include "vtkDenseArray.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkSmartPointer.h"
+#include "vtkSparseArray.h"
+#include "vtkTransposeMatrix.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// vtkTransposeMatrix
+
+vtkCxxRevisionMacro(vtkTransposeMatrix, "1.1");
+vtkStandardNewMacro(vtkTransposeMatrix);
+
+vtkTransposeMatrix::vtkTransposeMatrix()
+{
+}
+
+vtkTransposeMatrix::~vtkTransposeMatrix()
+{
+}
+
+void vtkTransposeMatrix::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+int vtkTransposeMatrix::RequestData(
+  vtkInformation*, 
+  vtkInformationVector** inputVector, 
+  vtkInformationVector* outputVector)
+{
+  vtkArrayData* const input = vtkArrayData::GetData(inputVector[0]);
+  vtkArrayData* const output = vtkArrayData::GetData(outputVector);
+
+  if(vtkSparseArray<double>* const input_array = vtkSparseArray<double>::SafeDownCast(input->GetArray()))
+    {
+    if(input_array->GetDimensions() != 2)
+      {
+      vtkErrorMacro(<< "vtkTransposeMatrix requires a matrix as input.");
+      return 0;
+      }
+
+    const vtkArrayExtents input_extents = input_array->GetExtents();
+
+    vtkSparseArray<double>* const output_array = vtkSparseArray<double>::New();
+    output->SetArray(output_array);
+    output_array->Delete();
+
+    output_array->Resize(vtkArrayExtents(input_extents[1], input_extents[0]));
+    output_array->SetDimensionLabel(0, input_array->GetDimensionLabel(1));
+    output_array->SetDimensionLabel(1, input_array->GetDimensionLabel(0));
+
+    vtkArrayCoordinates coordinates;
+    const vtkIdType element_count = input_array->GetNonNullSize();
+    for(vtkIdType n = 0; n != element_count; ++n)
+      {
+      input_array->GetCoordinatesN(n, coordinates);
+      output_array->AddValue(vtkArrayCoordinates(coordinates[1], coordinates[0]), input_array->GetValueN(n));
+      }
+    }
+  else if(vtkDenseArray<double>* const input_array = vtkDenseArray<double>::SafeDownCast(input->GetArray()))
+    {
+    if(input_array->GetDimensions() != 2)
+      {
+      vtkErrorMacro(<< "vtkTransposeMatrix requires a matrix as input.");
+      return 0;
+      }
+
+    const vtkArrayExtents input_extents = input_array->GetExtents();
+
+    vtkDenseArray<double>* const output_array = vtkDenseArray<double>::New();
+    output->SetArray(output_array);
+    output_array->Delete();
+
+    output_array->Resize(vtkArrayExtents(input_extents[1], input_extents[0]));
+    output_array->SetDimensionLabel(0, input_array->GetDimensionLabel(1));
+    output_array->SetDimensionLabel(1, input_array->GetDimensionLabel(0));
+
+    for(vtkIdType i = 0; i != input_extents[0]; ++i)
+      {
+      for(vtkIdType j = 0; j != input_extents[1]; ++j)
+        {
+        output_array->SetValue(vtkArrayCoordinates(j, i), input_array->GetValue(vtkArrayCoordinates(i, j)));
+        }
+      }
+    }
+  else
+    {
+    vtkErrorMacro(<< "Unsupported input array type.");
+    return 0;
+    }
+
+  return 1;
+}
+
diff --git a/Infovis/vtkTransposeMatrix.h b/Infovis/vtkTransposeMatrix.h
new file mode 100644
index 00000000000..0d59bc95393
--- /dev/null
+++ b/Infovis/vtkTransposeMatrix.h
@@ -0,0 +1,57 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkTransposeMatrix.h
+  
+-------------------------------------------------------------------------
+  Copyright 2008 Sandia Corporation.
+  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
+  the U.S. Government retains certain rights in this software.
+-------------------------------------------------------------------------
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#ifndef __vtkTransposeMatrix_h
+#define __vtkTransposeMatrix_h
+
+#include "vtkArrayDataAlgorithm.h"
+#include "vtkSetGet.h"
+
+class vtkArrayExtents;
+
+// .NAME vtkTransposeMatrix - Computes the transpose of an input matrix.
+
+// .SECTION Thanks
+// Developed by Timothy M. Shead (tshead@sandia.gov) at Sandia National Laboratories.
+
+class VTK_INFOVIS_EXPORT vtkTransposeMatrix : public vtkArrayDataAlgorithm
+{
+public:
+  static vtkTransposeMatrix* New();
+  vtkTypeRevisionMacro(vtkTransposeMatrix, vtkArrayDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+protected:
+  vtkTransposeMatrix();
+  ~vtkTransposeMatrix();
+
+  int RequestData(
+    vtkInformation*, 
+    vtkInformationVector**, 
+    vtkInformationVector*);
+
+private:
+  vtkTransposeMatrix(const vtkTransposeMatrix&); // Not implemented
+  void operator=(const vtkTransposeMatrix&);   // Not implemented
+};
+
+#endif
+
-- 
GitLab