Index: /branches/NCA/HeuristicLab.Algorithms.NCA.Tests/MatrixTest.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA.Tests/MatrixTest.cs	(revision 8436)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA.Tests/MatrixTest.cs	(revision 8437)
@@ -122,9 +122,9 @@
     public void LengthTest() {
       var vector = new double[] { 5, 4, 2, 2 };
-      Assert.AreEqual(new Matrix_Accessor(vector, vector.Length).Length(), 7);
+      Assert.AreEqual(new Matrix_Accessor(vector, vector.Length).VectorLength(), 7);
       vector = new double[] { 5, -4, 2, 2 };
-      Assert.AreEqual(new Matrix_Accessor(vector, vector.Length).Length(), 7);
+      Assert.AreEqual(new Matrix_Accessor(vector, vector.Length).VectorLength(), 7);
       vector = new double[] { 3, 2, 1, 5 };
-      Assert.IsTrue(new Matrix_Accessor(vector, vector.Length).Length().IsAlmost(6.2449979983983982058468931209398));
+      Assert.IsTrue(new Matrix_Accessor(vector, vector.Length).VectorLength().IsAlmost(6.2449979983983982058468931209398));
     }
 
Index: /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/HeuristicLab.Algorithms.NCA.Views-3.3.csproj
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/HeuristicLab.Algorithms.NCA.Views-3.3.csproj	(revision 8436)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/HeuristicLab.Algorithms.NCA.Views-3.3.csproj	(revision 8437)
@@ -168,9 +168,9 @@
   <ItemGroup>
     <None Include="Plugin.cs.frame" />
-    <Compile Include="NCADimensionalityReductionView.cs">
+    <Compile Include="NCADimensionReductionView.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="NCADimensionalityReductionView.Designer.cs">
-      <DependentUpon>NCADimensionalityReductionView.cs</DependentUpon>
+    <Compile Include="NCADimensionReductionView.Designer.cs">
+      <DependentUpon>NCADimensionReductionView.cs</DependentUpon>
     </Compile>
     <Compile Include="Plugin.cs" />
@@ -188,6 +188,6 @@
   </ItemGroup>
   <ItemGroup>
-    <EmbeddedResource Include="NCADimensionalityReductionView.resx">
-      <DependentUpon>NCADimensionalityReductionView.cs</DependentUpon>
+    <EmbeddedResource Include="NCADimensionReductionView.resx">
+      <DependentUpon>NCADimensionReductionView.cs</DependentUpon>
     </EmbeddedResource>
   </ItemGroup>
Index: /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionReductionView.Designer.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionReductionView.Designer.cs	(revision 8437)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionReductionView.Designer.cs	(revision 8437)
@@ -0,0 +1,134 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Algorithms.NCA.Views {
+  partial class NCADimensionReductionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.messageLabel = new System.Windows.Forms.Label();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.rangeLabel = new System.Windows.Forms.Label();
+      this.rangeComboBox = new System.Windows.Forms.ComboBox();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // messageLabel
+      // 
+      this.messageLabel.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.messageLabel.Location = new System.Drawing.Point(0, 0);
+      this.messageLabel.Name = "messageLabel";
+      this.messageLabel.Size = new System.Drawing.Size(300, 167);
+      this.messageLabel.TabIndex = 0;
+      this.messageLabel.Text = "Visualization is not supported for more than two dimensions.";
+      this.messageLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.splitContainer.IsSplitterFixed = true;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.rangeComboBox);
+      this.splitContainer.Panel1.Controls.Add(this.rangeLabel);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.messageLabel);
+      this.splitContainer.Size = new System.Drawing.Size(300, 198);
+      this.splitContainer.SplitterDistance = 27;
+      this.splitContainer.TabIndex = 1;
+      // 
+      // rangeLabel
+      // 
+      this.rangeLabel.AutoSize = true;
+      this.rangeLabel.Location = new System.Drawing.Point(3, 6);
+      this.rangeLabel.Name = "rangeLabel";
+      this.rangeLabel.Size = new System.Drawing.Size(47, 13);
+      this.rangeLabel.TabIndex = 0;
+      this.rangeLabel.Text = "Samples";
+      // 
+      // rangeComboBox
+      // 
+      this.rangeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.rangeComboBox.FormattingEnabled = true;
+      this.rangeComboBox.Items.AddRange(new object[] {
+            "Training",
+            "Test",
+            "All samples"});
+      this.rangeComboBox.Location = new System.Drawing.Point(56, 3);
+      this.rangeComboBox.Name = "rangeComboBox";
+      this.rangeComboBox.Size = new System.Drawing.Size(146, 21);
+      this.rangeComboBox.TabIndex = 1;
+      this.rangeComboBox.SelectedIndexChanged += new System.EventHandler(this.rangeComboBox_SelectedIndexChanged);
+      // 
+      // NCADimensionalityReductionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "NCADimensionalityReductionView";
+      this.Size = new System.Drawing.Size(300, 198);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label messageLabel;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.ComboBox rangeComboBox;
+    private System.Windows.Forms.Label rangeLabel;
+  }
+}
Index: /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionReductionView.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionReductionView.cs	(revision 8437)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionReductionView.cs	(revision 8437)
@@ -0,0 +1,101 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.Problems.DataAnalysis.Views;
+
+namespace HeuristicLab.Algorithms.NCA.Views {
+  [View("Dimension Reduction")]
+  [Content(typeof(INCAClassificationSolution), IsDefaultView = false)]
+  public partial class NCADimensionReductionView : DataAnalysisSolutionEvaluationView {
+    private ViewHost viewHost = new ViewHost();
+    private ScatterPlot scatterPlot = new ScatterPlot();
+
+    public new INCAClassificationSolution Content {
+      get { return (INCAClassificationSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public NCADimensionReductionView() {
+      InitializeComponent();
+      messageLabel.Visible = false;
+      viewHost.Dock = DockStyle.Fill;
+      splitContainer.Panel2.Controls.Add(viewHost);
+      rangeComboBox.SelectedIndex = 0;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        viewHost.Content = null;
+        scatterPlot.Rows.Clear();
+      } else {
+        UpdateScatterPlot();
+        viewHost.Content = scatterPlot;
+      }
+    }
+
+    private void UpdateScatterPlot() {
+      scatterPlot.Rows.Clear();
+      var rows = Content.ProblemData.ClassValues
+        .ToDictionary(c => c, c => new ScatterPlotDataRow(Content.ProblemData.GetClassName(c), string.Empty, Enumerable.Empty<Point2D<double>>()));
+
+      IEnumerable<int> range = null;
+      if (rangeComboBox.SelectedIndex == 0) range = Content.ProblemData.TrainingIndices;
+      else if (rangeComboBox.SelectedIndex == 1) range = Content.ProblemData.TestIndices;
+      else range = Enumerable.Range(0, Content.ProblemData.Dataset.Rows);
+
+      var reduced = Content.Model.Reduce(Content.ProblemData.Dataset, range);
+
+      int idx = 0;
+      if (reduced.GetLength(1) == 1) {
+        foreach (var r in range) {
+          var label = Content.ProblemData.Dataset.GetDoubleValue(Content.ProblemData.TargetVariable, r);
+          rows[label].Points.Add(new Point2D<double>(reduced[idx++, 0], 1.0));
+        }
+      } else {
+        foreach (var r in range) {
+          var label = Content.ProblemData.Dataset.GetDoubleValue(Content.ProblemData.TargetVariable, r);
+          rows[label].Points.Add(new Point2D<double>(reduced[idx, 0], reduced[idx, 1]));
+          idx++;
+        }
+      }
+      scatterPlot.Rows.AddRange(rows.Values);
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      rangeComboBox.Enabled = Content != null && viewHost.Visible;
+    }
+
+    #region Event Handlers
+    private void rangeComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
+      if (Content != null) UpdateScatterPlot();
+    }
+    #endregion
+  }
+}
Index: /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionReductionView.resx
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionReductionView.resx	(revision 8437)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionReductionView.resx	(revision 8437)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: anches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionalityReductionView.Designer.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionalityReductionView.Designer.cs	(revision 8436)
+++ 	(revision )
@@ -1,134 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-namespace HeuristicLab.Algorithms.NCA.Views {
-  partial class NCADimensionalityReductionView {
-    /// <summary> 
-    /// Required designer variable.
-    /// </summary>
-    private System.ComponentModel.IContainer components = null;
-
-    /// <summary> 
-    /// Clean up any resources being used.
-    /// </summary>
-    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-    protected override void Dispose(bool disposing) {
-      if (disposing && (components != null)) {
-        components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
-
-    #region Component Designer generated code
-
-    /// <summary> 
-    /// Required method for Designer support - do not modify 
-    /// the contents of this method with the code editor.
-    /// </summary>
-    private void InitializeComponent() {
-      this.messageLabel = new System.Windows.Forms.Label();
-      this.splitContainer = new System.Windows.Forms.SplitContainer();
-      this.rangeLabel = new System.Windows.Forms.Label();
-      this.rangeComboBox = new System.Windows.Forms.ComboBox();
-      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
-      this.splitContainer.Panel1.SuspendLayout();
-      this.splitContainer.Panel2.SuspendLayout();
-      this.splitContainer.SuspendLayout();
-      this.SuspendLayout();
-      // 
-      // messageLabel
-      // 
-      this.messageLabel.Dock = System.Windows.Forms.DockStyle.Fill;
-      this.messageLabel.Location = new System.Drawing.Point(0, 0);
-      this.messageLabel.Name = "messageLabel";
-      this.messageLabel.Size = new System.Drawing.Size(300, 167);
-      this.messageLabel.TabIndex = 0;
-      this.messageLabel.Text = "Visualization is not supported for more than two dimensions.";
-      this.messageLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
-      // 
-      // splitContainer
-      // 
-      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
-      this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
-      this.splitContainer.IsSplitterFixed = true;
-      this.splitContainer.Location = new System.Drawing.Point(0, 0);
-      this.splitContainer.Name = "splitContainer";
-      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
-      // 
-      // splitContainer.Panel1
-      // 
-      this.splitContainer.Panel1.Controls.Add(this.rangeComboBox);
-      this.splitContainer.Panel1.Controls.Add(this.rangeLabel);
-      // 
-      // splitContainer.Panel2
-      // 
-      this.splitContainer.Panel2.Controls.Add(this.messageLabel);
-      this.splitContainer.Size = new System.Drawing.Size(300, 198);
-      this.splitContainer.SplitterDistance = 27;
-      this.splitContainer.TabIndex = 1;
-      // 
-      // rangeLabel
-      // 
-      this.rangeLabel.AutoSize = true;
-      this.rangeLabel.Location = new System.Drawing.Point(3, 6);
-      this.rangeLabel.Name = "rangeLabel";
-      this.rangeLabel.Size = new System.Drawing.Size(47, 13);
-      this.rangeLabel.TabIndex = 0;
-      this.rangeLabel.Text = "Samples";
-      // 
-      // rangeComboBox
-      // 
-      this.rangeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-      this.rangeComboBox.FormattingEnabled = true;
-      this.rangeComboBox.Items.AddRange(new object[] {
-            "Training",
-            "Test",
-            "All samples"});
-      this.rangeComboBox.Location = new System.Drawing.Point(56, 3);
-      this.rangeComboBox.Name = "rangeComboBox";
-      this.rangeComboBox.Size = new System.Drawing.Size(146, 21);
-      this.rangeComboBox.TabIndex = 1;
-      this.rangeComboBox.SelectedIndexChanged += new System.EventHandler(this.rangeComboBox_SelectedIndexChanged);
-      // 
-      // NCADimensionalityReductionView
-      // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-      this.Controls.Add(this.splitContainer);
-      this.Name = "NCADimensionalityReductionView";
-      this.Size = new System.Drawing.Size(300, 198);
-      this.splitContainer.Panel1.ResumeLayout(false);
-      this.splitContainer.Panel1.PerformLayout();
-      this.splitContainer.Panel2.ResumeLayout(false);
-      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
-      this.splitContainer.ResumeLayout(false);
-      this.ResumeLayout(false);
-
-    }
-
-    #endregion
-
-    private System.Windows.Forms.Label messageLabel;
-    private System.Windows.Forms.SplitContainer splitContainer;
-    private System.Windows.Forms.ComboBox rangeComboBox;
-    private System.Windows.Forms.Label rangeLabel;
-  }
-}
Index: anches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionalityReductionView.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionalityReductionView.cs	(revision 8436)
+++ 	(revision )
@@ -1,121 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using System.Windows.Forms;
-using HeuristicLab.Analysis;
-using HeuristicLab.Common;
-using HeuristicLab.MainForm;
-using HeuristicLab.MainForm.WindowsForms;
-using HeuristicLab.Problems.DataAnalysis.Views;
-
-namespace HeuristicLab.Algorithms.NCA.Views {
-  [View("Dimensionality Reduction")]
-  [Content(typeof(NCAClassificationSolution), IsDefaultView = false)]
-  public partial class NCADimensionalityReductionView : DataAnalysisSolutionEvaluationView {
-    private ViewHost viewHost = new ViewHost();
-    private ScatterPlot scatterPlot = new ScatterPlot();
-
-    public new NCAClassificationSolution Content {
-      get { return (NCAClassificationSolution)base.Content; }
-      set { base.Content = value; }
-    }
-
-    public NCADimensionalityReductionView() {
-      InitializeComponent();
-      viewHost.Visible = false;
-      viewHost.Dock = DockStyle.Fill;
-      splitContainer.Panel2.Controls.Add(viewHost);
-      rangeComboBox.SelectedIndex = 0;
-    }
-
-    #region Register Content Events
-    protected override void DeregisterContentEvents() {
-      // TODO: Deregister your event handlers on the Content here
-      base.DeregisterContentEvents();
-    }
-    protected override void RegisterContentEvents() {
-      base.RegisterContentEvents();
-      // TODO: Register your event handlers on the Content here
-    }
-    #endregion
-
-    protected override void OnContentChanged() {
-      base.OnContentChanged();
-      if (Content == null) {
-        scatterPlot.Rows.Clear();
-        messageLabel.Visible = false;
-        viewHost.Visible = true;
-      } else {
-        var matrix = Content.Model.TransformationMatrix;
-        if (matrix.GetLength(1) != 2) {
-          messageLabel.Visible = true;
-          viewHost.Visible = false;
-        } else {
-          messageLabel.Visible = false;
-          viewHost.Content = null;
-          viewHost.Visible = true;
-          UpdateScatterPlot();
-          viewHost.Content = scatterPlot;
-        }
-      }
-    }
-
-    private void UpdateScatterPlot() {
-      var matrix = Content.Model.TransformationMatrix;
-      scatterPlot.Rows.Clear();
-      var rows = Content.ProblemData.ClassValues.ToDictionary(c => c, c => new ScatterPlotDataRow(Content.ProblemData.GetClassName(c), string.Empty, Enumerable.Empty<Point2D<double>>()));
-
-      IEnumerable<int> range = null;
-      if (rangeComboBox.SelectedIndex == 0) range = Content.ProblemData.TrainingIndices;
-      else if (rangeComboBox.SelectedIndex == 1) range = Content.ProblemData.TestIndices;
-      else range = Enumerable.Range(0, Content.ProblemData.Dataset.Rows);
-
-      foreach (var r in range) {
-        var label = Content.ProblemData.Dataset.GetDoubleValue(Content.ProblemData.TargetVariable, r);
-        var point = Scale(matrix, r).ToArray();
-        rows[label].Points.Add(new Point2D<double>(point[0], point[point.Length > 1 ? 1 : 0]));
-      }
-      scatterPlot.Rows.AddRange(rows.Values);
-    }
-
-    private IEnumerable<double> Scale(double[,] matrix, int row) {
-      var instance = Content.ProblemData.AllowedInputVariables.Select(v => Content.ProblemData.Dataset.GetDoubleValue(v, row));
-      for (int j = 0; j < matrix.GetLength(1); j++) {
-        int i = 0;
-        yield return instance.Sum(x => x * matrix[i++, j]);
-      }
-    }
-
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-      rangeComboBox.Enabled = Content != null && viewHost.Visible;
-    }
-
-
-    #region Event Handlers
-    private void rangeComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
-      if (Content != null) UpdateScatterPlot();
-    }
-    #endregion
-  }
-}
Index: anches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionalityReductionView.resx
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA.Views/3.3/NCADimensionalityReductionView.resx	(revision 8436)
+++ 	(revision )
@@ -1,120 +1,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-</root>
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Auxiliary.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Auxiliary.cs	(revision 8437)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Auxiliary.cs	(revision 8437)
@@ -0,0 +1,157 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Algorithms.DataAnalysis;
+using HeuristicLab.Common;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.NCA {
+  internal class Auxiliary {
+
+    public static INCAModel Train(IClassificationProblemData data, int k, int dimensions, INCAInitializer initializer) {
+      var instances = data.TrainingIndices.Count();
+      var attributes = data.AllowedInputVariables.Count();
+
+      double[] matrix = initializer.Initialize(data, dimensions);
+
+      alglib.mincgstate state;
+      alglib.mincgreport rep;
+
+      alglib.mincgcreate(matrix, out state);
+      alglib.mincgsetcond(state, 0, 0, 0, 20);
+      alglib.mincgoptimize(state, Gradient, null, new OptimizationInfo(data, dimensions));
+      alglib.mincgresults(state, out matrix, out rep);
+
+      var transformationMatrix = new double[attributes, dimensions];
+      var counter = 0;
+      for (var i = 0; i < attributes; i++)
+        for (var j = 0; j < dimensions; j++)
+          transformationMatrix[i, j] = matrix[counter++];
+
+      var transformedTrainingset = new double[instances, dimensions];
+      var rowCount = 0;
+      foreach (var r in data.TrainingIndices) {
+        var i = 0;
+        foreach (var v in data.AllowedInputVariables) {
+          var val = data.Dataset.GetDoubleValue(v, r);
+          for (var j = 0; j < dimensions; j++)
+            transformedTrainingset[rowCount, j] += val * transformationMatrix[i, j];
+          i++;
+        }
+        rowCount++;
+      }
+
+      var ds = data.Dataset;
+      var targetVariable = data.TargetVariable;
+      return new NCAModel(transformedTrainingset, transformationMatrix, k, data.TargetVariable, data.AllowedInputVariables,
+        data.TrainingIndices.Select(i => ds.GetDoubleValue(targetVariable, i)).ToArray());
+    }
+
+    private static void Gradient(double[] A, ref double func, double[] grad, object obj) {
+      var info = (OptimizationInfo)obj;
+      var data = info.Data;
+      var classes = info.TargetValues;
+      var instances = info.Instances;
+      var attributes = info.Attributes;
+
+      var AMatrix = new Matrix(A, A.Length / info.ReduceDimensions, info.ReduceDimensions);
+
+      alglib.sparsematrix probabilities;
+      alglib.sparsecreate(instances, instances, out probabilities);
+      var transformedDistances = new double[instances];
+      for (int i = 0; i < instances - 1; i++) {
+        var iVector = new Matrix(GetRow(data, i), data.GetLength(1));
+        var denom = 0.0;
+        for (int k = 0; k < instances; k++) {
+          if (k == i) continue;
+          var kVector = new Matrix(GetRow(data, k));
+          transformedDistances[k] = Math.Exp(-iVector.Multiply(AMatrix).Subtract(kVector.Multiply(AMatrix)).SquaredVectorLength());
+          denom += transformedDistances[k];
+        }
+        if (denom > 1e-05) {
+          for (int j = i + 1; j < instances; j++) {
+            if (i == j) continue;
+            var v = transformedDistances[j] / denom;
+            alglib.sparseset(probabilities, i, j, v);
+          }
+        }
+      }
+      alglib.sparseconverttocrs(probabilities); // needed to enumerate in order (top-down and left-right)
+
+      int t0 = 0, t1 = 0, r, c;
+      double val;
+      var pi = new double[instances];
+      while (alglib.sparseenumerate(probabilities, ref t0, ref t1, out r, out c, out val)) {
+        if (classes[r].IsAlmost(classes[c])) {
+          pi[r] += val;
+        }
+      }
+
+      var innerSum = new double[attributes, attributes];
+      while (alglib.sparseenumerate(probabilities, ref t0, ref t1, out r, out c, out val)) {
+        var vector = new Matrix(GetRow(data, r)).Subtract(new Matrix(GetRow(data, c)));
+        vector.OuterProduct(vector).Multiply(2.0 * val * pi[r]).AddTo(innerSum);
+
+        if (classes[r].IsAlmost(classes[c])) {
+          vector.OuterProduct(vector).Multiply(-2.0 * val).AddTo(innerSum);
+        }
+      }
+
+      func = -2.0 * pi.Sum();
+
+      r = 0;
+      var newGrad = AMatrix.Multiply(-2.0).Transpose().Multiply(new Matrix(innerSum)).Transpose();
+      foreach (var g in newGrad) {
+        grad[r++] = g;
+      }
+    }
+
+    #region Helpers
+    private static IEnumerable<double> GetRow(double[,] data, int row) {
+      for (int i = 0; i < data.GetLength(1); i++)
+        yield return data[row, i];
+    }
+
+    private class OptimizationInfo {
+      //public IClassificationProblemData ProblemData { get; private set; }
+      public Scaling Scaling { get; private set; }
+      public double[,] Data { get; private set; }
+      public double[] TargetValues { get; private set; }
+      public int ReduceDimensions { get; private set; }
+      public int Instances { get; private set; }
+      public int Attributes { get; private set; }
+
+      public OptimizationInfo(IClassificationProblemData data, int reduceDimensions) {
+        //this.ProblemData = data;
+        this.Scaling = new Scaling(data.Dataset, data.AllowedInputVariables, data.TrainingIndices);
+        this.Data = AlglibUtil.PrepareAndScaleInputMatrix(data.Dataset, data.AllowedInputVariables, data.TrainingIndices, Scaling);
+        this.TargetValues = data.Dataset.GetDoubleValues(data.TargetVariable, data.TrainingIndices).ToArray();
+        this.ReduceDimensions = reduceDimensions;
+        this.Instances = data.TrainingIndices.Count();
+        this.Attributes = data.AllowedInputVariables.Count();
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/HeuristicLab.Algorithms.NCA-3.3.csproj
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/HeuristicLab.Algorithms.NCA-3.3.csproj	(revision 8436)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/HeuristicLab.Algorithms.NCA-3.3.csproj	(revision 8437)
@@ -99,4 +99,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="INCAClassificationSolution.cs" />
     <Compile Include="Initialization\INCAInitializer.cs" />
     <Compile Include="INCAModel.cs" />
@@ -105,8 +106,8 @@
     <Compile Include="Initialization\RandomInitializer.cs" />
     <Compile Include="Matrix.cs" />
-    <Compile Include="NCA.cs" />
+    <Compile Include="NeighborhoodComponentsAnalysis.cs" />
     <Compile Include="NCAClassificationSolution.cs" />
     <Compile Include="NCAModel.cs" />
-    <Compile Include="NeighborhoodComponentsAnalysis.cs" />
+    <Compile Include="Auxiliary.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/INCAClassificationSolution.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/INCAClassificationSolution.cs	(revision 8437)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/INCAClassificationSolution.cs	(revision 8437)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.NCA {
+  public interface INCAClassificationSolution : IClassificationSolution {
+    new INCAModel Model { get; }
+  }
+}
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/INCAModel.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/INCAModel.cs	(revision 8436)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/INCAModel.cs	(revision 8437)
@@ -20,9 +20,10 @@
 #endregion
 
+using System.Collections.Generic;
 using HeuristicLab.Problems.DataAnalysis;
 
 namespace HeuristicLab.Algorithms.NCA {
   public interface INCAModel : IClassificationModel {
-    double[,] TransformationMatrix { get; }
+    double[,] Reduce(Dataset dataset, IEnumerable<int> rows);
   }
 }
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Initialization/RandomInitializer.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Initialization/RandomInitializer.cs	(revision 8436)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Initialization/RandomInitializer.cs	(revision 8437)
@@ -74,5 +74,5 @@
       var matrix = new double[attributes * dimensions];
       for (int i = 0; i < matrix.Length; i++)
-        matrix[i] = random.NextDouble() * range[i / dimensions];
+        matrix[i] = random.NextDouble() / range[i / dimensions];
 
       return matrix;
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Matrix.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Matrix.cs	(revision 8436)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Matrix.cs	(revision 8437)
@@ -125,7 +125,11 @@
     }
 
-    public double Length() {
+    public double VectorLength() {
+      return Math.Sqrt(SquaredVectorLength());
+    }
+
+    public double SquaredVectorLength() {
       if (Rows != 1) throw new ArgumentException("Length only works on vectors.");
-      return Math.Sqrt(values.Sum(x => x * x));
+      return values.Sum(x => x * x);
     }
 
Index: anches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCA.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCA.cs	(revision 8436)
+++ 	(revision )
@@ -1,94 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Linq;
-using HeuristicLab.Algorithms.DataAnalysis;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.PluginInfrastructure;
-using HeuristicLab.Problems.DataAnalysis;
-
-namespace HeuristicLab.Algorithms.NCA {
-  /// <summary>
-  /// Neighborhood Components Analysis
-  /// </summary>
-  [Item("NCA", "Neihborhood Components Analysis is described in J. Goldberger, S. Roweis, G. Hinton, R. Salakhutdinov. 2005. Neighbourhood Component Analysis. Advances in Neural Information Processing Systems, 17. pp. 513-520.")]
-  [Creatable("Data Analysis")]
-  [StorableClass]
-  public sealed class NCA : FixedDataAnalysisAlgorithm<IClassificationProblem> {
-    #region Parameter Properties
-    public IValueLookupParameter<IntValue> KParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["k"]; }
-    }
-    public IValueLookupParameter<IntValue> ReduceDimensionsParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["ReduceDimensions"]; }
-    }
-    private IConstrainedValueParameter<INCAInitializer> InitializationParameter {
-      get { return (IConstrainedValueParameter<INCAInitializer>)Parameters["Initialization"]; }
-    }
-    #endregion
-
-    #region Properties
-    public IntValue K {
-      get { return KParameter.Value; }
-    }
-    public IntValue ReduceDimensions {
-      get { return ReduceDimensionsParameter.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    private NCA(bool deserializing) : base(deserializing) { }
-    private NCA(NCA original, Cloner cloner) : base(original, cloner) { }
-    public NCA()
-      : base() {
-      Parameters.Add(new ValueLookupParameter<IntValue>("k", "The k for the nearest neighbor.", new IntValue(1)));
-      Parameters.Add(new ValueLookupParameter<IntValue>("ReduceDimensions", "The number of dimensions that NCA should reduce the data to.", new IntValue(2)));
-      Parameters.Add(new ConstrainedValueParameter<INCAInitializer>("Initialization", "Which method should be used to initialize the matrix. Typically LDA (linear discriminant analysis) should provide a good estimate."));
-
-      INCAInitializer defaultInitializer = null;
-      foreach (var initializer in ApplicationManager.Manager.GetInstances<INCAInitializer>().OrderBy(x => x.ItemName)) {
-        if (initializer is LDAInitializer) defaultInitializer = initializer;
-        InitializationParameter.ValidValues.Add(initializer);
-      }
-      if (defaultInitializer != null) InitializationParameter.Value = defaultInitializer;
-
-      Problem = new ClassificationProblem();
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new NCA(this, cloner);
-    }
-
-    public override void Prepare() {
-      if (Problem != null) base.Prepare();
-    }
-
-    protected override void Run() {
-      var classification = NeighborhoodComponentsAnalysis.CreateNCASolution((IClassificationProblemData)Problem.ProblemData.Clone(), K.Value, ReduceDimensions.Value, InitializationParameter.Value);
-      Results.Add(new Result("ClassificationSolution", "The classification solution.", classification));
-    }
-  }
-}
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAClassificationSolution.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAClassificationSolution.cs	(revision 8436)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAClassificationSolution.cs	(revision 8437)
@@ -28,5 +28,5 @@
   [Item("NCAClassificationSolution", "")]
   [StorableClass]
-  public class NCAClassificationSolution : ClassificationSolution {
+  public class NCAClassificationSolution : ClassificationSolution, INCAClassificationSolution {
 
     public new INCAModel Model {
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAModel.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAModel.cs	(revision 8436)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAModel.cs	(revision 8437)
@@ -129,4 +129,20 @@
       return CreateClassificationSolution(problemData);
     }
+
+    public double[,] Reduce(Dataset dataset, IEnumerable<int> rows) {
+      var result = new double[rows.Count(), transformationMatrix.GetLength(1)];
+      int v = 0;
+      foreach (var r in rows) {
+        int i = 0;
+        foreach (var variable in allowedInputVariables) {
+          double val = dataset.GetDoubleValue(variable, r);
+          for (int j = 0; j < result.GetLength(1); j++)
+            result[v, j] += val * transformationMatrix[i, j];
+          i++;
+        }
+        v++;
+      }
+      return result;
+    }
   }
 }
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NeighborhoodComponentsAnalysis.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NeighborhoodComponentsAnalysis.cs	(revision 8436)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NeighborhoodComponentsAnalysis.cs	(revision 8437)
@@ -1,3 +1,3 @@
-﻿#region License Information
+#region License Information
 /* HeuristicLab
  * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
@@ -20,123 +20,80 @@
 #endregion
 
-using System;
-using System.Collections.Generic;
 using System.Linq;
+using HeuristicLab.Algorithms.DataAnalysis;
 using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
 using HeuristicLab.Problems.DataAnalysis;
 
 namespace HeuristicLab.Algorithms.NCA {
-  public class NeighborhoodComponentsAnalysis {
+  /// <summary>
+  /// Neighborhood Components Analysis
+  /// </summary>
+  [Item("Neighborhood Components Analysis", "NCA is described in J. Goldberger, S. Roweis, G. Hinton, R. Salakhutdinov. 2005. Neighbourhood Component Analysis. Advances in Neural Information Processing Systems, 17. pp. 513-520.")]
+  [Creatable("Data Analysis")]
+  [StorableClass]
+  public sealed class NeighborhoodComponentsAnalysis : FixedDataAnalysisAlgorithm<IClassificationProblem> {
+    #region Parameter Properties
+    public IValueLookupParameter<IntValue> KParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["k"]; }
+    }
+    public IValueLookupParameter<IntValue> ReduceDimensionsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["ReduceDimensions"]; }
+    }
+    private IConstrainedValueParameter<INCAInitializer> InitializationParameter {
+      get { return (IConstrainedValueParameter<INCAInitializer>)Parameters["Initialization"]; }
+    }
+    #endregion
 
-    public static INCAModel Train(IClassificationProblemData data, int k, int reduceDimensions, INCAInitializer initializer) {
-      var instances = data.TrainingIndices.Count();
-      var attributes = data.AllowedInputVariables.Count();
+    #region Properties
+    public IntValue K {
+      get { return KParameter.Value; }
+    }
+    public IntValue ReduceDimensions {
+      get { return ReduceDimensionsParameter.Value; }
+    }
+    #endregion
 
-      double[] matrix = initializer.Initialize(data, reduceDimensions);
+    [StorableConstructor]
+    private NeighborhoodComponentsAnalysis(bool deserializing) : base(deserializing) { }
+    private NeighborhoodComponentsAnalysis(NeighborhoodComponentsAnalysis original, Cloner cloner) : base(original, cloner) { }
+    public NeighborhoodComponentsAnalysis()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("k", "The k for the nearest neighbor.", new IntValue(1)));
+      Parameters.Add(new ValueLookupParameter<IntValue>("ReduceDimensions", "The number of dimensions that NCA should reduce the data to.", new IntValue(2)));
+      Parameters.Add(new ConstrainedValueParameter<INCAInitializer>("Initialization", "Which method should be used to initialize the matrix. Typically LDA (linear discriminant analysis) should provide a good estimate."));
 
-      alglib.mincgstate state;
-      alglib.mincgreport rep;
+      INCAInitializer defaultInitializer = null;
+      foreach (var initializer in ApplicationManager.Manager.GetInstances<INCAInitializer>().OrderBy(x => x.ItemName)) {
+        if (initializer is LDAInitializer) defaultInitializer = initializer;
+        InitializationParameter.ValidValues.Add(initializer);
+      }
+      if (defaultInitializer != null) InitializationParameter.Value = defaultInitializer;
 
-      // first run
-      alglib.mincgcreate(matrix, out state);
-      alglib.mincgsetcond(state, 0.0000000001, 0, 0, 0);
-      alglib.mincgoptimize(state, Gradient, null, new OptimizationInfo(data, reduceDimensions));
-      alglib.mincgresults(state, out matrix, out rep);
-
-      var transformationMatrix = new double[attributes, reduceDimensions];
-      var counter = 0;
-      for (var i = 0; i < attributes; i++)
-        for (var j = 0; j < reduceDimensions; j++)
-          transformationMatrix[i, j] = matrix[counter++];
-
-      var transformedTrainingset = new double[instances, reduceDimensions];
-      var rowCount = 0;
-      foreach (var r in data.TrainingIndices) {
-        var i = 0;
-        foreach (var v in data.AllowedInputVariables) {
-          var val = data.Dataset.GetDoubleValue(v, r);
-          for (var j = 0; j < reduceDimensions; j++)
-            transformedTrainingset[rowCount, j] += val * transformationMatrix[i, j];
-          i++;
-        }
-        rowCount++;
-      }
-
-      return new NCAModel(transformedTrainingset, transformationMatrix, k, data.TargetVariable, data.AllowedInputVariables,
-        data.Dataset.GetDoubleValues(data.TargetVariable)
-          .Select((v, i) => new { I = i, V = v })
-          .Where(x => x.I >= data.TrainingPartition.Start && x.I < data.TrainingPartition.End
-              && !(x.I >= data.TestPartition.Start && x.I < data.TestPartition.End))
-          .Select(x => x.V).ToArray());
+      Problem = new ClassificationProblem();
     }
 
-    private static void Gradient(double[] A, ref double func, double[] grad, object obj) {
-      var info = (OptimizationInfo)obj;
-      var instances = info.ProblemData.TrainingIndices.ToArray();
-      var attributes = info.ProblemData.AllowedInputVariables.Count();
-      var AMatrix = new Matrix(A, A.Length / info.ReduceDimensions, info.ReduceDimensions);
-
-      alglib.sparsematrix probabilities;
-      alglib.sparsecreate(instances.Length, instances.Length, out probabilities);
-      var distances = new double[instances.Length];
-      for (int i = 0; i < instances.Length - 1; i++) {
-        var iVector = new Matrix(GetRow(info.ProblemData, instances[i]));
-        var denom = 0.0;
-        for (int k = 0; k < instances.Length; k++) {
-          if (k == i) continue;
-          var kVector = new Matrix(GetRow(info.ProblemData, instances[k]));
-          distances[k] = iVector.Multiply(AMatrix).Subtract(kVector.Multiply(AMatrix)).Length();
-          denom += Math.Exp(-(distances[k] * distances[k]));
-        }
-        if (denom > 0) {
-          for (int j = i + 1; j < instances.Length; j++) {
-            if (i == j) continue;
-            var v = Math.Exp(-(distances[j] * distances[j])) / denom;
-            alglib.sparseset(probabilities, i, j, v);
-            alglib.sparseset(probabilities, j, i, v);
-          }
-        }
-      }
-      alglib.sparseconverttocrs(probabilities); // needed to enumerate in order (top-down and left-right)
-
-      int t0 = 0, t1 = 0, r, c;
-      double val;
-      var classes = info.ProblemData.Dataset.GetDoubleValues(info.ProblemData.TargetVariable, instances).ToArray();
-      var pi = new double[instances.Length];
-      while (alglib.sparseenumerate(probabilities, ref t0, ref t1, out r, out c, out val)) {
-        if (classes[r].IsAlmost(classes[c]))
-          pi[r] += val;
-      }
-
-      var innerSum = new double[attributes, attributes];
-      while (alglib.sparseenumerate(probabilities, ref t0, ref t1, out r, out c, out val)) {
-        var vector = new Matrix(GetRow(info.ProblemData, instances[r])).Subtract(new Matrix(GetRow(info.ProblemData, instances[c]))).Apply();
-        vector.OuterProduct(vector).Multiply(val * pi[r]).AddTo(innerSum);
-
-        if (classes[r].IsAlmost(classes[c])) {
-          vector.OuterProduct(vector).Multiply(-val).AddTo(innerSum);
-        }
-      }
-
-      func = -pi.Sum();
-
-      grad = AMatrix.Multiply(-2.0).Transpose().Multiply(new Matrix(innerSum)).Transpose().ToArray();
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NeighborhoodComponentsAnalysis(this, cloner);
     }
 
-    private static IEnumerable<double> GetRow(IClassificationProblemData data, int row) {
-      return data.AllowedInputVariables.Select(v => data.Dataset.GetDoubleValue(v, row));
+    public override void Prepare() {
+      if (Problem != null) base.Prepare();
     }
 
-    public static NCAClassificationSolution CreateNCASolution(IClassificationProblemData problemData, int k, int reduceDimensions, INCAInitializer initializer) {
-      return new NCAClassificationSolution(problemData, Train(problemData, k, reduceDimensions, initializer));
-    }
+    protected override void Run() {
+      var k = K.Value;
+      var dimensions = ReduceDimensions.Value;
+      var initializer = InitializationParameter.Value;
 
-    private class OptimizationInfo {
-      public IClassificationProblemData ProblemData { get; set; }
-      public int ReduceDimensions { get; set; }
-      public OptimizationInfo(IClassificationProblemData problem, int reduceDimensions) {
-        this.ProblemData = problem;
-        this.ReduceDimensions = reduceDimensions;
-      }
+      var clonedProblem = (IClassificationProblemData)Problem.ProblemData.Clone();
+      var classification = new NCAClassificationSolution(clonedProblem, Auxiliary.Train(clonedProblem, k, dimensions, initializer));
+      Results.Add(new Result("ClassificationSolution", "The classification solution.", classification));
+      // TODO: result that shows the LOO performance
     }
   }
Index: /branches/NCA/NCA.sln
===================================================================
--- /branches/NCA/NCA.sln	(revision 8436)
+++ /branches/NCA/NCA.sln	(revision 8437)
@@ -3,6 +3,4 @@
 # Visual Studio 2010
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.NCA-3.3", "HeuristicLab.Algorithms.NCA\3.3\HeuristicLab.Algorithms.NCA-3.3.csproj", "{FD81A5D6-051D-4BD1-B2D8-668A820FAD6E}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.NCA.Views-3.3", "HeuristicLab.Algorithms.NCA.Views\3.3\HeuristicLab.Algorithms.NCA.Views-3.3.csproj", "{07654A26-5964-4079-B023-5548B1EB1D1E}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{30CDFA65-3AD8-42A4-801E-0F785CE9DF16}"
@@ -15,4 +13,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.NCA.Tests", "HeuristicLab.Algorithms.NCA.Tests\HeuristicLab.Algorithms.NCA.Tests.csproj", "{910C130C-378D-422B-96B7-0484F7CC66B7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.NCA.Views-3.3", "HeuristicLab.Algorithms.NCA.Views\3.3\HeuristicLab.Algorithms.NCA.Views-3.3.csproj", "{07654A26-5964-4079-B023-5548B1EB1D1E}"
 EndProject
 Global
@@ -37,4 +37,12 @@
 		{FD81A5D6-051D-4BD1-B2D8-668A820FAD6E}.Release|x64.ActiveCfg = Release|Any CPU
 		{FD81A5D6-051D-4BD1-B2D8-668A820FAD6E}.Release|x86.ActiveCfg = Release|Any CPU
+		{910C130C-378D-422B-96B7-0484F7CC66B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{910C130C-378D-422B-96B7-0484F7CC66B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{910C130C-378D-422B-96B7-0484F7CC66B7}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{910C130C-378D-422B-96B7-0484F7CC66B7}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{910C130C-378D-422B-96B7-0484F7CC66B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{910C130C-378D-422B-96B7-0484F7CC66B7}.Release|Any CPU.Build.0 = Release|Any CPU
+		{910C130C-378D-422B-96B7-0484F7CC66B7}.Release|x64.ActiveCfg = Release|Any CPU
+		{910C130C-378D-422B-96B7-0484F7CC66B7}.Release|x86.ActiveCfg = Release|Any CPU
 		{07654A26-5964-4079-B023-5548B1EB1D1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{07654A26-5964-4079-B023-5548B1EB1D1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
@@ -49,12 +57,4 @@
 		{07654A26-5964-4079-B023-5548B1EB1D1E}.Release|x86.ActiveCfg = Release|x86
 		{07654A26-5964-4079-B023-5548B1EB1D1E}.Release|x86.Build.0 = Release|x86
-		{910C130C-378D-422B-96B7-0484F7CC66B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{910C130C-378D-422B-96B7-0484F7CC66B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{910C130C-378D-422B-96B7-0484F7CC66B7}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{910C130C-378D-422B-96B7-0484F7CC66B7}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{910C130C-378D-422B-96B7-0484F7CC66B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{910C130C-378D-422B-96B7-0484F7CC66B7}.Release|Any CPU.Build.0 = Release|Any CPU
-		{910C130C-378D-422B-96B7-0484F7CC66B7}.Release|x64.ActiveCfg = Release|Any CPU
-		{910C130C-378D-422B-96B7-0484F7CC66B7}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
