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 8412)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/HeuristicLab.Algorithms.NCA-3.3.csproj	(revision 8412)
@@ -0,0 +1,124 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{FD81A5D6-051D-4BD1-B2D8-668A820FAD6E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Algorithms.NCA</RootNamespace>
+    <AssemblyName>HeuristicLab.Algorithms.NCA-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ALGLIB-3.5.0">
+      <HintPath>..\..\..\..\trunk\sources\bin\ALGLIB-3.5.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.4">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="INCAModel.cs" />
+    <Compile Include="NCA.cs" />
+    <Compile Include="NCAClassificationSolution.cs" />
+    <Compile Include="NCAModel.cs" />
+    <Compile Include="NeighborhoodComponentsAnalysis.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/HeuristicLab.Algorithms.NCA-3.3.csproj.user
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/HeuristicLab.Algorithms.NCA-3.3.csproj.user	(revision 8412)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/HeuristicLab.Algorithms.NCA-3.3.csproj.user	(revision 8412)
@@ -0,0 +1,10 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectView>ProjectFiles</ProjectView>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
+    <StartAction>Program</StartAction>
+    <StartProgram>C:\Users\Don\Work\HL3\trunk\sources\bin\HeuristicLab 3.3.exe</StartProgram>
+  </PropertyGroup>
+</Project>
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/INCAModel.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/INCAModel.cs	(revision 8412)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/INCAModel.cs	(revision 8412)
@@ -0,0 +1,26 @@
+﻿#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 INCAModel : IClassificationModel { }
+}
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCA.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCA.cs	(revision 8412)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCA.cs	(revision 8412)
@@ -0,0 +1,81 @@
+#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.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.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("Algorithms")]
+  [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"]; }
+    }
+    #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)));
+
+      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(Problem.ProblemData, K.Value, ReduceDimensions.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 8412)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAClassificationSolution.cs	(revision 8412)
@@ -0,0 +1,55 @@
+﻿#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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.NCA {
+  [Item("NCAClassificationSolution", "")]
+  [StorableClass]
+  public class NCAClassificationSolution : ClassificationSolution {
+
+    public new INCAModel Model {
+      get { return (INCAModel)base.Model; }
+      set { base.Model = value; }
+    }
+
+    [StorableConstructor]
+    private NCAClassificationSolution(bool deserializing) : base(deserializing) { }
+    private NCAClassificationSolution(NCAClassificationSolution original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public NCAClassificationSolution(IClassificationProblemData problemData, INCAModel ncaModel)
+      : base(ncaModel, problemData) {
+      RecalculateResults();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NCAClassificationSolution(this, cloner);
+    }
+
+    protected override void RecalculateResults() {
+      CalculateResults();
+    }
+  }
+}
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAModel.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAModel.cs	(revision 8412)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAModel.cs	(revision 8412)
@@ -0,0 +1,126 @@
+﻿#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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.NCA {
+  [Item("NCAModel", "")]
+  [StorableClass]
+  public class NCAModel : NamedItem, INCAModel {
+
+    [Storable]
+    private string targetVariable;
+    [Storable]
+    private string[] allowedInputVariables;
+    [Storable]
+    private double[] classValues;
+    [Storable]
+    private int k;
+    [Storable]
+    private double[,] transformationMatrix;
+    /// <summary>
+    /// Get a clone of the transformation matrix
+    /// </summary>
+    public double[,] TransformationMatrix {
+      get { return (double[,])transformationMatrix.Clone(); }
+    }
+    [Storable]
+    private double[,] transformedTrainingset;
+    /// <summary>
+    /// Get a clone of the transformed trainingset
+    /// </summary>
+    public double[,] TransformedTrainingset {
+      get { return (double[,])transformedTrainingset.Clone(); }
+    }
+
+    [StorableConstructor]
+    protected NCAModel(bool deserializing) : base(deserializing) { }
+    protected NCAModel(NCAModel original, Cloner cloner)
+      : base(original, cloner) {
+      k = original.k;
+      targetVariable = original.targetVariable;
+      allowedInputVariables = (string[])original.allowedInputVariables.Clone();
+      if (original.classValues != null)
+        this.classValues = (double[])original.classValues.Clone();
+      if (original.transformationMatrix != null)
+        this.transformationMatrix = (double[,])original.transformationMatrix.Clone();
+      if (original.transformedTrainingset != null)
+        this.transformedTrainingset = (double[,])original.transformedTrainingset.Clone();
+    }
+    public NCAModel(double[,] transformedTrainingset, double[,] transformationMatrix, int k, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues = null)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.transformedTrainingset = transformedTrainingset;
+      this.transformationMatrix = transformationMatrix;
+      this.k = k;
+      this.targetVariable = targetVariable;
+      this.allowedInputVariables = allowedInputVariables.ToArray();
+      if (classValues != null)
+        this.classValues = (double[])classValues.Clone();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NCAModel(this, cloner);
+    }
+
+    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
+      int k = Math.Min(this.k, transformedTrainingset.GetLength(0));
+      double[] transformedRow = new double[transformationMatrix.GetLength(1)];
+      var kVotes = new SortedList<double, double>(k + 1);
+      foreach (var r in rows) {
+        for (int i = 0; i < transformedRow.Length; i++) transformedRow[i] = 0;
+        int j = 0;
+        foreach (var v in allowedInputVariables) {
+          double val = dataset.GetDoubleValue(v, r);
+          for (int i = 0; i < transformedRow.Length; i++)
+            transformedRow[i] += val * transformationMatrix[j, i];
+          j++;
+        }
+        kVotes.Clear();
+        for (int a = 0; a < transformedTrainingset.GetLength(0); a++) {
+          double d = 0;
+          for (int y = 0; y < transformedRow.Length; y++) {
+            d += (transformedRow[y] - transformedTrainingset[a, y]) * (transformedRow[y] - transformedTrainingset[a, y]);
+          }
+          while (kVotes.ContainsKey(d)) d += 1e-12;
+          if (kVotes.Count <= k || kVotes.Last().Key > d) {
+            kVotes.Add(d, classValues[a]);
+            if (kVotes.Count > k) kVotes.RemoveAt(kVotes.Count - 1);
+          }
+        }
+        yield return kVotes.Values.ToLookup(x => x).MaxItems(x => x.Count()).First().Key;
+      }
+    }
+    public NCAClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new NCAClassificationSolution(problemData, this);
+    }
+    IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
+      return CreateClassificationSolution(problemData);
+    }
+  }
+}
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NeighborhoodComponentsAnalysis.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NeighborhoodComponentsAnalysis.cs	(revision 8412)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NeighborhoodComponentsAnalysis.cs	(revision 8412)
@@ -0,0 +1,223 @@
+﻿#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.Common;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.NCA {
+  public class NeighborhoodComponentsAnalysis {
+
+    public static INCAModel Train(IClassificationProblemData data, int k, int reduceDimensions) {
+      var instances = data.TrainingIndices.Count();
+      var attributes = data.AllowedInputVariables.Count();
+      var matrix = new double[attributes * reduceDimensions];
+      // TODO: make some more clever initialization of matrix
+      for (var i = 0; i < attributes; i++)
+        for (var j = 0; j < reduceDimensions; j++)
+          matrix[j * attributes + i] = 1;
+
+      alglib.mincgstate state;
+      alglib.mincgreport rep;
+
+      // 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];
+      for (var i = 0; i < attributes; i++)
+        for (var j = 0; j < reduceDimensions; j++)
+          transformationMatrix[i, j] = matrix[j * attributes + i];
+
+      var transformedTrainingset = new double[instances, reduceDimensions];
+      var rowCount = 0;
+      for (var r = data.TrainingPartition.Start; r < data.TrainingPartition.End; r++) {
+        if (r >= data.TestPartition.Start && r < data.TestPartition.End) continue;
+        var j = 0;
+        foreach (var v in data.AllowedInputVariables) {
+          var val = data.Dataset.GetDoubleValue(v, r);
+          for (var i = 0; i < transformedTrainingset.GetLength(1); i++)
+            transformedTrainingset[rowCount, i] += val * transformationMatrix[j, i];
+          j++;
+        }
+        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());
+    }
+
+    private static void Gradient(double[] A, ref double func, double[] grad, object obj) {
+      var info = (OptimizationInfo)obj;
+      var instances = info.ProblemData.TrainingIndices.ToArray();
+      var distances = new double[instances.Length, instances.Length];
+      for (int i = 0; i < instances.Length - 1; i++) {
+        for (int j = i + 1; j < instances.Length; j++) {
+          distances[i, j] = VectorLength(VectorSubtract(
+            Ax(A, GetRow(info.ProblemData, instances[i])),
+            Ax(A, GetRow(info.ProblemData, instances[j]))));
+          distances[j, i] = distances[i, j];
+        }
+      }
+      var probabilities = new double[instances.Length, instances.Length];
+      for (int i = 0; i < instances.Length - 1; i++) {
+        var denom = 0.0;
+        for (int k = 0; k < instances.Length; k++) {
+          if (k == i) continue;
+          denom += Math.Exp(-(distances[i, k] * distances[i, k]));
+        }
+        for (int j = i + 1; j < instances.Length; j++) {
+          probabilities[i, j] = Math.Exp(-(distances[i, j] * distances[i, j])) / denom;
+        }
+      }
+
+      var target = info.ProblemData.TargetVariable;
+      var ds = info.ProblemData.Dataset;
+      var pi = new double[instances.Length];
+      func = 0.0;
+      for (int i = 0; i < instances.Length; i++) {
+        var classI = ds.GetDoubleValue(target, instances[i]);
+        pi[i] = 0.0;
+        for (int j = 0; j < instances.Length; j++) {
+          if (i == j) continue;
+          var classJ = ds.GetDoubleValue(target, instances[j]);
+          if (classI.IsAlmost(classJ)) {
+            func += probabilities[i, j];
+            pi[i] += probabilities[i, j];
+          }
+        }
+      }
+
+      var sum = GetSum(probabilities, pi, info.ProblemData, instances);
+      for (int i = 0; i < A.Length; i++) {
+        grad[i] = 2.0 * A[i] * sum;
+      }
+    }
+
+    private static double[,] GetSum(double[,] p, double[] pi, IClassificationProblemData data, int[] instances) {
+      var target = data.TargetVariable;
+      var sum = new double[pi.Length, pi.Length];
+      for (int i = 0; i < pi.Length; i++) {
+        var classI = data.Dataset.GetDoubleValue(target, instances[i]);
+        var sumK = 0.0;
+        for (int k = 0; k < pi.Length; k++) {
+          if (i == k) continue;
+          sumK += p[i, k] * MatrixMultiply(VectorSubtract(GetRow(data, i), GetRow(data, k)), VectorSubtract(GetRow(data, i), GetRow(data, k)));
+        }
+        var sumJ = 0.0;
+        for (int j = 0; j < pi.Length; j++) {
+          if (i == j) continue;
+          var classJ = data.Dataset.GetDoubleValue(target, instances[j]);
+          if (classI.IsAlmost(classJ)) sumJ += p[i, j] * ScalarProduct(VectorSubtract(GetRow(data, i), GetRow(data, j)), VectorSubtract(GetRow(data, i), GetRow(data, j)));
+        }
+        sum += pi[i] * sumK - sumJ;
+      }
+      return sum;
+    }
+
+    private static double[,] MatrixMultiply(IEnumerable<double> vec1, IEnumerable<double> vec2) {
+      var enumVec1 = vec1.GetEnumerator();
+      var enumVec2 = vec2.GetEnumerator();
+      bool f1, f2;
+      while (true) {
+        f1 = enumVec1.MoveNext();
+        f2 = enumVec2.MoveNext();
+        if (!f1 && f2 || f1 && !f2) throw new ArgumentException("vectors are of unequal length.");
+        if (!f1 && !f2) yield break;
+        yield return enumVec1.Current - enumVec2.Current;
+      }
+    }
+
+    private static IEnumerable<double> Ax(IEnumerable<double> A, IEnumerable<double> x) {
+      var enumA = A.GetEnumerator();
+      var enumX = x.GetEnumerator();
+      var sum = 0.0;
+      while (true) {
+        if (!enumA.MoveNext()) {
+          yield return sum;
+          yield break;
+        } else if (!enumX.MoveNext()) {
+          yield return sum;
+          enumX = x.GetEnumerator();
+          sum = 0.0;
+        } else {
+          sum += enumA.Current * enumX.Current;
+        }
+      }
+    }
+
+    private static IEnumerable<double> GetRow(IClassificationProblemData data, int row) {
+      return data.AllowedInputVariables.Select(v => data.Dataset.GetDoubleValue(v, row));
+    }
+
+    private static IEnumerable<double> VectorSubtract(IEnumerable<double> vec1, IEnumerable<double> vec2) {
+      var enumVec1 = vec1.GetEnumerator();
+      var enumVec2 = vec2.GetEnumerator();
+      bool f1, f2;
+      while (true) {
+        f1 = enumVec1.MoveNext();
+        f2 = enumVec2.MoveNext();
+        if (!f1 && f2 || f1 && !f2) throw new ArgumentException("vectors are of unequal length.");
+        if (!f1 && !f2) yield break;
+        yield return enumVec1.Current - enumVec2.Current;
+      }
+    }
+
+    private static double ScalarProduct(IEnumerable<double> vec1, IEnumerable<double> vec2) {
+      var enumVec1 = vec1.GetEnumerator();
+      var enumVec2 = vec2.GetEnumerator();
+      bool f1, f2;
+      double product = 0.0;
+      while (true) {
+        f1 = enumVec1.MoveNext();
+        f2 = enumVec2.MoveNext();
+        if (!f1 && f2 || f1 && !f2) throw new ArgumentException("vectors are of unequal length.");
+        if (!f1 && !f2) return product;
+        product += enumVec1.Current * enumVec2.Current;
+      }
+    }
+
+    private static double VectorLength(IEnumerable<double> vector) {
+      return Math.Sqrt(vector.Sum(x => x * x));
+    }
+
+    public static NCAClassificationSolution CreateNCASolution(IClassificationProblemData problemData, int k, int reduceDimensions) {
+      return new NCAClassificationSolution(problemData, Train(problemData, k, reduceDimensions));
+    }
+
+    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;
+      }
+    }
+  }
+}
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Plugin.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Plugin.cs	(revision 8412)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Plugin.cs	(revision 8412)
@@ -0,0 +1,40 @@
+﻿#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.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.NCA {
+  [Plugin("HeuristicLab.Algorithms.NCA", "3.3.7.0")]
+  [PluginFile("HeuristicLab.Algorithms.NCA-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Algorithms.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
+  public class HeuristicLabAlgorithmsNCAPlugin : PluginBase {
+  }
+}
Index: /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Properties/AssemblyInfo.cs
===================================================================
--- /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Properties/AssemblyInfo.cs	(revision 8412)
+++ /branches/NCA/HeuristicLab.Algorithms.NCA/3.3/Properties/AssemblyInfo.cs	(revision 8412)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Algorithms.NCA")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HEAL")]
+[assembly: AssemblyProduct("HeuristicLAb")]
+[assembly: AssemblyCopyright("(c) 2002-2012 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("cf00e562-11c6-4dff-997f-b5989111d0e0")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.7.0")]
Index: /branches/NCA/NCA.sln
===================================================================
--- /branches/NCA/NCA.sln	(revision 8412)
+++ /branches/NCA/NCA.sln	(revision 8412)
@@ -0,0 +1,20 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 11.00
+# 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
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{FD81A5D6-051D-4BD1-B2D8-668A820FAD6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{FD81A5D6-051D-4BD1-B2D8-668A820FAD6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{FD81A5D6-051D-4BD1-B2D8-668A820FAD6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{FD81A5D6-051D-4BD1-B2D8-668A820FAD6E}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
