Index: trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/HeuristicLab.ArtificialNeuralNetworks-3.2.csproj
===================================================================
--- trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/HeuristicLab.ArtificialNeuralNetworks-3.2.csproj	(revision 2562)
+++ trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/HeuristicLab.ArtificialNeuralNetworks-3.2.csproj	(revision 2562)
@@ -0,0 +1,157 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{4744FB81-7F42-4BBA-813E-68CAB6FE07E2}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.ArtificialNeuralNetworks</RootNamespace>
+    <AssemblyName>HeuristicLab.ArtificialNeuralNetworks-3.2</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</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 Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="MultiLayerPerceptron.cs" />
+    <Compile Include="HeuristicLabArtificialNeuralNetworksPlugin.cs" />
+    <Compile Include="MultiLayerPerceptronRegression.cs" />
+    <Compile Include="MultiLayerPerceptronRegressionOperator.cs" />
+    <Compile Include="Predictor.cs" />
+    <Compile Include="PredictorBuilder.cs" />
+    <Compile Include="MultiLayerPerceptronEvaluator.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\ALGLIB\ALGLIB.csproj">
+      <Project>{44456535-5DB5-454A-BE2B-7426DA6700B6}</Project>
+      <Name>ALGLIB</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.2\HeuristicLab.Core-3.2.csproj">
+      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
+      <Name>HeuristicLab.Core-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.DataAnalysis\3.2\HeuristicLab.DataAnalysis-3.2.csproj">
+      <Project>{7DD3A97A-56E9-462F-90E2-A351FE7AF5C2}</Project>
+      <Name>HeuristicLab.DataAnalysis-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.2\HeuristicLab.Data-3.2.csproj">
+      <Project>{F473D9AF-3F09-4296-9F28-3C65118DAFFA}</Project>
+      <Name>HeuristicLab.Data-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Modeling\3.2\HeuristicLab.Modeling-3.2.csproj">
+      <Project>{80F7FADA-549D-4151-8856-79B620A50DBA}</Project>
+      <Name>HeuristicLab.Modeling-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Operators.Programmable\3.2\HeuristicLab.Operators.Programmable-3.2.csproj">
+      <Project>{E3CCBFC6-900C-41B6-AFB8-6646DB097435}</Project>
+      <Name>HeuristicLab.Operators.Programmable-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Operators\3.2\HeuristicLab.Operators-3.2.csproj">
+      <Project>{A9983BA2-B3B2-475E-8E2C-62050B71D1C5}</Project>
+      <Name>HeuristicLab.Operators-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Random\3.2\HeuristicLab.Random-3.2.csproj">
+      <Project>{47019A74-F7F7-482E-83AA-D3F4F777E879}</Project>
+      <Name>HeuristicLab.Random-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Selection\3.2\HeuristicLab.Selection-3.2.csproj">
+      <Project>{F7CF0571-25CB-43D5-8443-0843A1E2861A}</Project>
+      <Name>HeuristicLab.Selection-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.SequentialEngine\3.2\HeuristicLab.SequentialEngine-3.2.csproj">
+      <Project>{B4BE8E53-BA06-4237-9A01-24255F880201}</Project>
+      <Name>HeuristicLab.SequentialEngine-3.2</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.frame" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- 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>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/HeuristicLabArtificialNeuralNetworksPlugin.cs
===================================================================
--- trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/HeuristicLabArtificialNeuralNetworksPlugin.cs	(revision 2562)
+++ trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/HeuristicLabArtificialNeuralNetworksPlugin.cs	(revision 2562)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.ArtificialNeuralNetworks {
+  [ClassInfo(Name = "HeuristicLab.ArtificialNeuralNetworks-3.2")]
+  [PluginFile(Filename = "HeuristicLab.ArtificialNeuralNetworks.dll", Filetype = PluginFileType.Assembly)]
+  [Dependency(Dependency = "ALGLIB")]
+  [Dependency(Dependency = "HeuristicLab.Core-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Data-3.2")]
+  [Dependency(Dependency = "HeuristicLab.DataAnalysis-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Modeling-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Operators-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Operators.Programmable-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Random-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Selection-3.2")]
+  [Dependency(Dependency = "HeuristicLab.SequentialEngine-3.2")]
+  public class HeuristicLabArtificialNeuralNetworks : PluginBase {
+  }
+}
Index: trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptron.cs
===================================================================
--- trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptron.cs	(revision 2562)
+++ trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptron.cs	(revision 2562)
@@ -0,0 +1,103 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Core;
+using System.Xml;
+using System.Linq;
+using System.Globalization;
+
+namespace HeuristicLab.ArtificialNeuralNetworks {
+
+  public class MultiLayerPerceptron : ItemBase {
+    private alglib.mlpbase.multilayerperceptron perceptron;
+    public alglib.mlpbase.multilayerperceptron Perceptron {
+      get { return perceptron; }
+      internal set { perceptron = value; }
+    }
+
+    private List<string> inputVariables;
+    public IEnumerable<string> InputVariables {
+      get {
+        return inputVariables;
+      }
+    }
+    
+    private int minTimeOffset;
+    public int MinTimeOffset {
+      get { return minTimeOffset; }
+    }
+    private int maxTimeOffset;
+    public int MaxTimeOffset {
+      get { return maxTimeOffset; }
+    }
+
+    public MultiLayerPerceptron() : base() { } // for persistence;
+
+    public MultiLayerPerceptron(alglib.mlpbase.multilayerperceptron perceptron, IEnumerable<string> inputVariables, 
+      int minTimeOffset, int maxTimeOffset)
+      : base() {
+      this.perceptron = perceptron;
+      this.minTimeOffset = minTimeOffset;
+      this.maxTimeOffset = maxTimeOffset;
+      this.inputVariables = new List<string>(inputVariables);
+    }
+
+    public override object Clone(IDictionary<Guid, object> clonedObjects) {
+      MultiLayerPerceptron clone = (MultiLayerPerceptron)base.Clone(clonedObjects);
+
+      clone.inputVariables = new List<string>(inputVariables);
+
+      double[] ra = null;
+      int rlen = 0;
+      alglib.mlpbase.mlpserialize(ref perceptron, ref ra, ref rlen); // output: ra, rlen
+      alglib.mlpbase.mlpunserialize(ref ra, ref clone.perceptron); // output clone.perceptron
+      return clone;
+    }
+
+    public override System.Xml.XmlNode GetXmlNode(string name, System.Xml.XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
+
+      XmlNode networkInformation = document.CreateElement("NetworkInformation");
+      double[] ra = null;
+      int rlen = 0;
+      alglib.mlpbase.mlpserialize(ref perceptron, ref ra, ref rlen);
+      networkInformation.InnerText = String.Join(";", ra.Select(x => x.ToString("r", CultureInfo.InvariantCulture)).ToArray()); // culture invariant & round trip
+      node.AppendChild(networkInformation);
+
+      XmlNode inputVariablesNode = document.CreateElement("InputVariables");
+      inputVariablesNode.InnerText = String.Join(";", inputVariables.ToArray());
+      node.AppendChild(inputVariablesNode);
+      return node;
+    }
+
+    public override void Populate(System.Xml.XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
+      base.Populate(node, restoredObjects);
+      double[] ra = (from s in node.SelectSingleNode("NetworkInformation").InnerText.Split(';')
+                     select double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
+      alglib.mlpbase.mlpunserialize(ref ra, ref perceptron);
+
+      inputVariables = new List<string>(node.SelectSingleNode("InputVariables").InnerText.Split(';'));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptronEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptronEvaluator.cs	(revision 2562)
+++ trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptronEvaluator.cs	(revision 2562)
@@ -0,0 +1,81 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2009 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 System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.ArtificialNeuralNetworks {
+  public class MultiLayerPerceptronEvaluator : OperatorBase {
+
+    public MultiLayerPerceptronEvaluator()
+      : base() {
+      //Dataset infos
+      AddVariableInfo(new VariableInfo("Dataset", "Dataset with all samples on which to apply the function", typeof(Dataset), VariableKind.In));
+      AddVariableInfo(new VariableInfo("TargetVariable", "Name of the target variable", typeof(StringData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("InputVariables", "List of allowed input variable names", typeof(ItemList), VariableKind.In));
+      AddVariableInfo(new VariableInfo("SamplesStart", "Start index of samples in dataset to evaluate", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("SamplesEnd", "End index of samples in dataset to evaluate", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTimeOffset", "(optional) Maximal allowed time offset for input variables", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MinTimeOffset", "(optional) Minimal allowed time offset for input variables", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MultiLayerPerceptron", "Represent the model learned by the SVM", typeof(MultiLayerPerceptron), VariableKind.In));
+      AddVariableInfo(new VariableInfo("Values", "Target vs predicted values", typeof(DoubleMatrixData), VariableKind.New | VariableKind.Out));
+    }
+
+
+    public override IOperation Apply(IScope scope) {
+      Dataset dataset = GetVariableValue<Dataset>("Dataset", scope, true);
+      ItemList inputVariables = GetVariableValue<ItemList>("InputVariables", scope, true);
+      var inputVariableNames = from x in inputVariables
+                               select ((StringData)x).Data;
+      string targetVariable = GetVariableValue<StringData>("TargetVariable", scope, true).Data;
+      int targetVariableIndex = dataset.GetVariableIndex(targetVariable);
+      int start = GetVariableValue<IntData>("SamplesStart", scope, true).Data;
+      int end = GetVariableValue<IntData>("SamplesEnd", scope, true).Data;
+      IntData minTimeOffsetData = GetVariableValue<IntData>("MinTimeOffset", scope, true, false);
+      int minTimeOffset = minTimeOffsetData == null ? 0 : minTimeOffsetData.Data;
+      IntData maxTimeOffsetData = GetVariableValue<IntData>("MaxTimeOffset", scope, true, false);
+      int maxTimeOffset = maxTimeOffsetData == null ? 0 : maxTimeOffsetData.Data;
+      MultiLayerPerceptron model = GetVariableValue<MultiLayerPerceptron>("MultiLayerPerceptron", scope, true);
+
+      double[,] values = new double[end - start, 2];
+      for (int i = 0; i < end - start; i++) {
+        double[] output = new double[1];
+        double[] inputRow = new double[dataset.Columns - 1];
+        for (int c = 1; c < inputRow.Length; c++) {
+          inputRow[c - 1] = dataset.GetValue(i + start, c);
+        }
+        alglib.mlpbase.multilayerperceptron p = model.Perceptron;
+        alglib.mlpbase.mlpprocess(ref p, ref inputRow, ref output);
+        model.Perceptron = p;
+        values[i, 0] = dataset.GetValue(start + i, targetVariableIndex);
+        values[i, 1] = output[0];
+      }
+
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("Values"), new DoubleMatrixData(values)));
+      return null;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptronRegression.cs
===================================================================
--- trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptronRegression.cs	(revision 2562)
+++ trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptronRegression.cs	(revision 2562)
@@ -0,0 +1,443 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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 System.Text;
+using HeuristicLab.Core;
+using System.Xml;
+using System.Diagnostics;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.Data;
+using HeuristicLab.Modeling;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using HeuristicLab.Selection;
+using HeuristicLab.Operators.Programmable;
+
+namespace HeuristicLab.ArtificialNeuralNetworks {
+  public class MultiLayerPerceptronRegression : ItemBase, IEditable, IAlgorithm {
+
+    public virtual string Name { get { return "MultiLayerPerceptronRegression"; } }
+    public virtual string Description { get { return "TODO"; } }
+
+    private IEngine engine;
+    public virtual IEngine Engine {
+      get { return engine; }
+    }
+
+    public virtual Dataset Dataset {
+      get { return ProblemInjector.GetVariableValue<Dataset>("Dataset", null, false); }
+      set { ProblemInjector.GetVariable("Dataset").Value = value; }
+    }
+
+    public virtual string TargetVariable {
+      get { return ProblemInjector.GetVariableValue<StringData>("TargetVariable", null, false).Data; }
+      set { ProblemInjector.GetVariableValue<StringData>("TargetVariable", null, false).Data = value; }
+    }
+
+    public virtual IOperator ProblemInjector {
+      get {
+        IOperator main = GetMainOperator();
+        CombinedOperator probInjector = (CombinedOperator)main.SubOperators[2];
+        return probInjector.OperatorGraph.InitialOperator.SubOperators[0];
+      }
+      set {
+        IOperator main = GetMainOperator();
+        CombinedOperator probInjector = (CombinedOperator)main.SubOperators[2];
+        probInjector.OperatorGraph.InitialOperator.RemoveSubOperator(0);
+        probInjector.OperatorGraph.InitialOperator.AddSubOperator(value, 0);
+      }
+    }
+    public IEnumerable<string> AllowedVariables {
+      get {
+        ItemList<StringData> allowedVariables = ProblemInjector.GetVariableValue<ItemList<StringData>>("AllowedFeatures", null, false);
+        return allowedVariables.Select(x => x.Data);
+      }
+      set {
+        ItemList<StringData> allowedVariables = ProblemInjector.GetVariableValue<ItemList<StringData>>("AllowedFeatures", null, false);
+        foreach (string x in value) allowedVariables.Add(new StringData(x));
+      }
+    }
+
+    public int TrainingSamplesStart {
+      get { return ProblemInjector.GetVariableValue<IntData>("TrainingSamplesStart", null, false).Data; }
+      set { ProblemInjector.GetVariableValue<IntData>("TrainingSamplesStart", null, false).Data = value; }
+    }
+
+    public int TrainingSamplesEnd {
+      get { return ProblemInjector.GetVariableValue<IntData>("TrainingSamplesEnd", null, false).Data; }
+      set { ProblemInjector.GetVariableValue<IntData>("TrainingSamplesEnd", null, false).Data = value; }
+    }
+
+    public int ValidationSamplesStart {
+      get { return ProblemInjector.GetVariableValue<IntData>("ValidationSamplesStart", null, false).Data; }
+      set { ProblemInjector.GetVariableValue<IntData>("ValidationSamplesStart", null, false).Data = value; }
+    }
+
+    public int ValidationSamplesEnd {
+      get { return ProblemInjector.GetVariableValue<IntData>("ValidationSamplesEnd", null, false).Data; }
+      set { ProblemInjector.GetVariableValue<IntData>("ValidationSamplesEnd", null, false).Data = value; }
+    }
+
+    public int TestSamplesStart {
+      get { return ProblemInjector.GetVariableValue<IntData>("TestSamplesStart", null, false).Data; }
+      set { ProblemInjector.GetVariableValue<IntData>("TestSamplesStart", null, false).Data = value; }
+    }
+
+    public int TestSamplesEnd {
+      get { return ProblemInjector.GetVariableValue<IntData>("TestSamplesEnd", null, false).Data; }
+      set { ProblemInjector.GetVariableValue<IntData>("TestSamplesEnd", null, false).Data = value; }
+    }
+
+    public IntArrayData NumberOfHiddenNodesList {
+      get { return GetVariableInjector().GetVariable("NumberOfHiddenNodesList").GetValue<IntArrayData>(); }
+      set { GetVariableInjector().GetVariable("NumberOfHiddenNodesList").Value = value; }
+    }
+
+    public int MaxNumberOfHiddenNodesListIndex {
+      get { return GetVariableInjector().GetVariable("MaxNumberOfHiddenNodesIndex").GetValue<IntData>().Data; }
+      set { GetVariableInjector().GetVariable("MaxNumberOfHiddenNodesIndex").GetValue<IntData>().Data = value; }
+    }
+
+    public virtual IAnalyzerModel Model {
+      get {
+        if (!engine.Terminated) throw new InvalidOperationException("The algorithm is still running. Wait until the algorithm is terminated to retrieve the result.");
+        IScope bestModelScope = engine.GlobalScope;
+        return CreateLRModel(bestModelScope);
+      }
+    }
+
+    public MultiLayerPerceptronRegression() {
+      engine = new SequentialEngine.SequentialEngine();
+      CombinedOperator algo = CreateAlgorithm();
+      engine.OperatorGraph.AddOperator(algo);
+      engine.OperatorGraph.InitialOperator = algo;
+      MaxNumberOfHiddenNodesListIndex = NumberOfHiddenNodesList.Data.Length;
+    }
+
+    protected virtual CombinedOperator CreateAlgorithm() {
+      CombinedOperator algo = new CombinedOperator();
+      SequentialProcessor seq = new SequentialProcessor();
+      algo.Name = Name;
+      seq.Name = Name;
+
+      IOperator globalInjector = CreateGlobalInjector();
+
+      IOperator mainLoop = CreateMainLoop();
+
+      seq.AddSubOperator(globalInjector);
+      seq.AddSubOperator(new RandomInjector());
+      seq.AddSubOperator(CreateProblemInjector());
+      seq.AddSubOperator(mainLoop);
+      seq.AddSubOperator(CreatePostProcessingOperator());
+
+      algo.OperatorGraph.InitialOperator = seq;
+      algo.OperatorGraph.AddOperator(seq);
+
+      return algo;
+    }
+
+    private IOperator CreateMainLoop() {
+      SequentialProcessor seq = new SequentialProcessor();
+
+      #region initial solution
+      SubScopesCreater modelScopeCreator = new SubScopesCreater();
+      modelScopeCreator.GetVariableInfo("SubScopes").Local = true;
+      modelScopeCreator.AddVariable(new HeuristicLab.Core.Variable("SubScopes", new IntData(1)));
+      seq.AddSubOperator(modelScopeCreator);
+
+      SequentialSubScopesProcessor seqSubScopesProc = new SequentialSubScopesProcessor();
+      IOperator modelProcessor = CreateModelProcessor();
+
+      seqSubScopesProc.AddSubOperator(modelProcessor);
+      seq.AddSubOperator(seqSubScopesProc);
+      #endregion
+
+
+      Counter nHiddenNodesCounter = new Counter();
+      nHiddenNodesCounter.GetVariableInfo("Value").ActualName = "NumberOfHiddenNodesIndex";
+      nHiddenNodesCounter.Name = "NumberOfHiddenNodesIndexCounter";
+
+      LessThanComparator comparator = new LessThanComparator();
+      comparator.Name = "NumberOfHiddenNodesIndexComparator";
+      comparator.GetVariableInfo("LeftSide").ActualName = "NumberOfHiddenNodesIndex";
+      comparator.GetVariableInfo("RightSide").ActualName = "MaxNumberOfHiddenNodesIndex";
+      comparator.GetVariableInfo("Result").ActualName = "RepeatNumberOfHiddenNodesIndexLoop";
+
+      ConditionalBranch branch = new ConditionalBranch();
+      branch.Name = "IfValidNumberOfHiddenNodesIndex";
+      branch.GetVariableInfo("Condition").ActualName = "RepeatNumberOfHiddenNodesIndexLoop";
+
+
+
+      // build loop
+      SequentialProcessor loop = new SequentialProcessor();
+      loop.Name = "HiddenNodesLoop";
+
+      #region selection of better solution
+
+      loop.AddSubOperator(modelScopeCreator);
+      SequentialSubScopesProcessor subScopesProcessor = new SequentialSubScopesProcessor();
+      loop.AddSubOperator(subScopesProcessor);
+      subScopesProcessor.AddSubOperator(new EmptyOperator());
+      subScopesProcessor.AddSubOperator(CreateModelProcessor());
+
+      Sorter sorter = new Sorter();
+      sorter.GetVariableInfo("Value").ActualName = "ValidationQuality";
+      sorter.GetVariableInfo("Descending").Local = true;
+      sorter.AddVariable(new Variable("Descending", new BoolData(false)));
+      loop.AddSubOperator(sorter);
+
+      LeftSelector selector = new LeftSelector();
+      selector.GetVariableInfo("Selected").Local = true;
+      selector.AddVariable(new Variable("Selected", new IntData(1)));
+      loop.AddSubOperator(selector);
+
+      RightReducer reducer = new RightReducer();
+      loop.AddSubOperator(reducer);
+      #endregion
+
+      loop.AddSubOperator(nHiddenNodesCounter);
+      loop.AddSubOperator(comparator);
+
+      branch.AddSubOperator(loop);
+      loop.AddSubOperator(branch);
+
+
+      seq.AddSubOperator(loop);
+      return seq;
+    }
+
+    private IOperator CreateModelProcessor() {
+      SequentialProcessor modelProcessor = new SequentialProcessor();
+      modelProcessor.AddSubOperator(CreateSetNextParameterValueOperator("NumberOfHiddenNodes"));
+
+      MultiLayerPerceptronRegressionOperator trainingOperator = new MultiLayerPerceptronRegressionOperator();
+      trainingOperator.GetVariableInfo("NumberOfHiddenLayerNeurons").ActualName = "NumberOfHiddenNodes";
+      trainingOperator.GetVariableInfo("SamplesStart").ActualName = "ActualTrainingSamplesStart";
+      trainingOperator.GetVariableInfo("SamplesEnd").ActualName = "ActualTrainingSamplesEnd";
+
+      modelProcessor.AddSubOperator(trainingOperator);
+      CombinedOperator trainingEvaluator = (CombinedOperator)CreateEvaluator("ActualTraining");
+      trainingEvaluator.OperatorGraph.InitialOperator.SubOperators[1].GetVariableInfo("MSE").ActualName = "Quality";
+      modelProcessor.AddSubOperator(trainingEvaluator);
+      modelProcessor.AddSubOperator(CreateEvaluator("Validation"));
+
+      DataCollector collector = new DataCollector();
+      collector.GetVariableInfo("Values").ActualName = "Log";
+      ((ItemList<StringData>)collector.GetVariable("VariableNames").Value).Add(new StringData("NumberOfHiddenNodes"));
+      ((ItemList<StringData>)collector.GetVariable("VariableNames").Value).Add(new StringData("ValidationQuality"));
+      modelProcessor.AddSubOperator(collector);
+      return modelProcessor;
+    }
+
+    protected virtual IOperator CreateEvaluator(string p) {
+      CombinedOperator op = new CombinedOperator();
+      op.Name = p + "Evaluator";
+      SequentialProcessor seqProc = new SequentialProcessor();
+
+      MultiLayerPerceptronEvaluator evaluator = new MultiLayerPerceptronEvaluator();
+      evaluator.Name = p + "SimpleEvaluator";
+      evaluator.GetVariableInfo("SamplesStart").ActualName = p + "SamplesStart";
+      evaluator.GetVariableInfo("SamplesEnd").ActualName = p + "SamplesEnd";
+      evaluator.GetVariableInfo("Values").ActualName = p + "Values";
+      SimpleMSEEvaluator mseEvaluator = new SimpleMSEEvaluator();
+      mseEvaluator.Name = p + "MseEvaluator";
+      mseEvaluator.GetVariableInfo("Values").ActualName = p + "Values";
+      mseEvaluator.GetVariableInfo("MSE").ActualName = p + "Quality";
+      SimpleR2Evaluator r2Evaluator = new SimpleR2Evaluator();
+      r2Evaluator.Name = p + "R2Evaluator";
+      r2Evaluator.GetVariableInfo("Values").ActualName = p + "Values";
+      r2Evaluator.GetVariableInfo("R2").ActualName = p + "R2";
+      SimpleMeanAbsolutePercentageErrorEvaluator mapeEvaluator = new SimpleMeanAbsolutePercentageErrorEvaluator();
+      mapeEvaluator.Name = p + "MAPEEvaluator";
+      mapeEvaluator.GetVariableInfo("Values").ActualName = p + "Values";
+      mapeEvaluator.GetVariableInfo("MAPE").ActualName = p + "MAPE";
+      SimpleMeanAbsolutePercentageOfRangeErrorEvaluator mapreEvaluator = new SimpleMeanAbsolutePercentageOfRangeErrorEvaluator();
+      mapreEvaluator.Name = p + "MAPREEvaluator";
+      mapreEvaluator.GetVariableInfo("Values").ActualName = p + "Values";
+      mapreEvaluator.GetVariableInfo("MAPRE").ActualName = p + "MAPRE";
+      SimpleVarianceAccountedForEvaluator vafEvaluator = new SimpleVarianceAccountedForEvaluator();
+      vafEvaluator.Name = p + "VAFEvaluator";
+      vafEvaluator.GetVariableInfo("Values").ActualName = p + "Values";
+      vafEvaluator.GetVariableInfo("VAF").ActualName = p + "VAF";
+
+      seqProc.AddSubOperator(evaluator);
+      seqProc.AddSubOperator(mseEvaluator);
+      seqProc.AddSubOperator(r2Evaluator);
+      seqProc.AddSubOperator(mapeEvaluator);
+      seqProc.AddSubOperator(mapreEvaluator);
+      seqProc.AddSubOperator(vafEvaluator);
+
+      op.OperatorGraph.AddOperator(seqProc);
+      op.OperatorGraph.InitialOperator = seqProc;
+      return op;
+    }
+
+    private IOperator CreateSetNextParameterValueOperator(string paramName) {
+      ProgrammableOperator progOp = new ProgrammableOperator();
+      progOp.Name = "SetNext" + paramName;
+      progOp.RemoveVariableInfo("Result");
+      progOp.AddVariableInfo(new VariableInfo("Value", "Value", typeof(IntData), VariableKind.New));
+      progOp.AddVariableInfo(new VariableInfo("ValueIndex", "ValueIndex", typeof(IntData), VariableKind.In));
+      progOp.AddVariableInfo(new VariableInfo("ValueList", "ValueList", typeof(IntArrayData), VariableKind.In));
+      progOp.Code =
+@"
+Value.Data = ValueList.Data[ValueIndex.Data];
+";
+
+      progOp.GetVariableInfo("Value").ActualName = paramName;
+      progOp.GetVariableInfo("ValueIndex").ActualName = paramName + "Index";
+      progOp.GetVariableInfo("ValueList").ActualName = paramName + "List";
+      return progOp;
+    }
+
+
+    protected virtual IOperator CreateProblemInjector() {
+      return DefaultRegressionOperators.CreateProblemInjector();
+    }
+
+    protected virtual VariableInjector CreateGlobalInjector() {
+      VariableInjector injector = new VariableInjector();
+
+      injector.AddVariable(new HeuristicLab.Core.Variable("MaxNumberOfTrainingSamples", new IntData(4000)));
+      injector.AddVariable(new HeuristicLab.Core.Variable("PunishmentFactor", new DoubleData(1000)));
+      injector.AddVariable(new HeuristicLab.Core.Variable("NumberOfHiddenNodesIndex", new IntData(0)));
+      injector.AddVariable(new HeuristicLab.Core.Variable("MaxNumberOfHiddenNodesIndex", new IntData(0)));
+      injector.AddVariable(new HeuristicLab.Core.Variable("NumberOfHiddenNodesList", new IntArrayData(new int[] { 2, 4, 8, 16, 32, 64, 128 })));
+      injector.AddVariable(new HeuristicLab.Core.Variable("Log", new ItemList()));
+      return injector;
+    }
+
+    protected virtual IOperator CreatePostProcessingOperator() {
+      CombinedOperator op = new CombinedOperator();
+      op.Name = "Model Analyzer";
+
+      SequentialSubScopesProcessor seqSubScopesProc = new SequentialSubScopesProcessor();
+
+      SequentialProcessor seq = new SequentialProcessor();
+
+      seqSubScopesProc.AddSubOperator(seq);
+
+      #region simple evaluators
+      MultiLayerPerceptronEvaluator trainingEvaluator = new MultiLayerPerceptronEvaluator();
+      trainingEvaluator.GetVariableInfo("SamplesStart").ActualName = "TrainingSamplesStart";
+      trainingEvaluator.GetVariableInfo("SamplesEnd").ActualName = "TrainingSamplesEnd";
+      trainingEvaluator.GetVariableInfo("Values").ActualName = "TrainingValues";
+
+      MultiLayerPerceptronEvaluator testEvaluator = new MultiLayerPerceptronEvaluator();
+      testEvaluator.GetVariableInfo("SamplesStart").ActualName = "TestSamplesStart";
+      testEvaluator.GetVariableInfo("SamplesEnd").ActualName = "TestSamplesEnd";
+      testEvaluator.GetVariableInfo("Values").ActualName = "TestValues";
+
+      seq.AddSubOperator(trainingEvaluator);
+      seq.AddSubOperator(testEvaluator);
+      #endregion
+
+      #region variable impacts
+      // calculate and set variable impacts
+
+      PredictorBuilder predictorBuilder = new PredictorBuilder();
+
+      seq.AddSubOperator(predictorBuilder);
+      VariableQualityImpactCalculator qualityImpactCalculator = new VariableQualityImpactCalculator();
+      qualityImpactCalculator.GetVariableInfo("SamplesStart").ActualName = "TrainingSamplesStart";
+      qualityImpactCalculator.GetVariableInfo("SamplesEnd").ActualName = "TrainingSamplesEnd";
+
+      seq.AddSubOperator(qualityImpactCalculator);
+      #endregion
+
+      seq.AddSubOperator(CreateModelAnalyzerOperator());
+
+
+
+
+      op.OperatorGraph.AddOperator(seqSubScopesProc);
+      op.OperatorGraph.InitialOperator = seqSubScopesProc;
+      return op;
+    }
+
+    protected virtual IOperator CreateModelAnalyzerOperator() {
+      return DefaultRegressionOperators.CreatePostProcessingOperator();
+    }
+
+    protected virtual IAnalyzerModel CreateLRModel(IScope bestModelScope) {
+      var model = new AnalyzerModel();
+      CreateSpecificLRModel(bestModelScope, model);
+      #region variable impacts
+      ItemList qualityImpacts = bestModelScope.GetVariableValue<ItemList>(ModelingResult.VariableQualityImpact.ToString(), false);
+      foreach (ItemList row in qualityImpacts) {
+        string variableName = ((StringData)row[0]).Data;
+        double impact = ((DoubleData)row[1]).Data;
+        model.SetVariableResult(ModelingResult.VariableQualityImpact, variableName, impact);
+        model.AddInputVariable(variableName);
+      }
+      #endregion
+      return model;
+    }
+
+    protected virtual void CreateSpecificLRModel(IScope bestModelScope, IAnalyzerModel model) {
+      DefaultRegressionOperators.PopulateAnalyzerModel(bestModelScope, model);
+    }
+
+    protected virtual IOperator GetMainOperator() {
+      CombinedOperator lr = (CombinedOperator)Engine.OperatorGraph.InitialOperator;
+      return lr.OperatorGraph.InitialOperator;
+    }
+
+    protected virtual IOperator GetVariableInjector() {
+      return GetMainOperator().SubOperators[0];
+    }
+
+    public override IView CreateView() {
+      return engine.CreateView();
+    }
+
+    #region IEditable Members
+
+    public virtual IEditor CreateEditor() {
+      return ((SequentialEngine.SequentialEngine)engine).CreateEditor();
+    }
+
+    #endregion
+
+    #region persistence
+    public override object Clone(IDictionary<Guid, object> clonedObjects) {
+      MultiLayerPerceptronRegression clone = (MultiLayerPerceptronRegression)base.Clone(clonedObjects);
+      clone.engine = (IEngine)Auxiliary.Clone(Engine, clonedObjects);
+      return clone;
+    }
+
+    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
+      node.AppendChild(PersistenceManager.Persist("Engine", engine, document, persistedObjects));
+      return node;
+    }
+
+    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
+      base.Populate(node, restoredObjects);
+      engine = (IEngine)PersistenceManager.Restore(node.SelectSingleNode("Engine"), restoredObjects);
+    }
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptronRegressionOperator.cs
===================================================================
--- trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptronRegressionOperator.cs	(revision 2562)
+++ trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/MultiLayerPerceptronRegressionOperator.cs	(revision 2562)
@@ -0,0 +1,163 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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 System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.Modeling;
+
+namespace HeuristicLab.ArtificialNeuralNetworks {
+  public class MultiLayerPerceptronRegressionOperator : OperatorBase {
+
+    public MultiLayerPerceptronRegressionOperator() {
+      AddVariableInfo(new VariableInfo("TargetVariable", "Name of the target variable", typeof(StringData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("Dataset", "Dataset with all samples on which to apply the function", typeof(Dataset), VariableKind.In));
+      AddVariableInfo(new VariableInfo("SamplesStart", "Start index of samples in dataset to evaluate", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("SamplesEnd", "End index of samples in dataset to evaluate", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("NumberOfHiddenLayerNeurons", "The number of nodes in the hidden layer.", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTimeOffset", "(optional) Maximal time offset for time-series prognosis", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MinTimeOffset", "(optional) Minimal time offset for time-series prognosis", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MultiLayerPerceptron", "Formula that was calculated by multi layer perceptron regression", typeof(MultiLayerPerceptron), VariableKind.Out | VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      Dataset dataset = GetVariableValue<Dataset>("Dataset", scope, true);
+      string targetVariable = GetVariableValue<StringData>("TargetVariable", scope, true).Data;
+      int targetVariableIndex = dataset.GetVariableIndex(targetVariable);
+      int start = GetVariableValue<IntData>("SamplesStart", scope, true).Data;
+      int end = GetVariableValue<IntData>("SamplesEnd", scope, true).Data;
+      IntData maxTimeOffsetData = GetVariableValue<IntData>("MaxTimeOffset", scope, true, false);
+      int maxTimeOffset = maxTimeOffsetData == null ? 0 : maxTimeOffsetData.Data;
+      IntData minTimeOffsetData = GetVariableValue<IntData>("MinTimeOffset", scope, true, false);
+      int minTimeOffset = minTimeOffsetData == null ? 0 : minTimeOffsetData.Data;
+      int nHiddenNodes = GetVariableValue<IntData>("NumberOfHiddenLayerNeurons", scope, true).Data;
+
+      var perceptron = CreateModel(dataset, targetVariable, dataset.VariableNames, start, end, minTimeOffset, maxTimeOffset, nHiddenNodes);
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("MultiLayerPerceptron"), perceptron));
+      return null;
+    }
+
+    public static MultiLayerPerceptron CreateModel(Dataset dataset, string targetVariable, IEnumerable<string> inputVariables, int start, int end, int nHiddenNodes) {
+      return CreateModel(dataset, targetVariable, inputVariables, start, end, 0, 0, nHiddenNodes);
+    }
+
+    public static MultiLayerPerceptron CreateModel(Dataset dataset, string targetVariable, IEnumerable<string> inputVariables,
+        int start, int end,
+        int minTimeOffset, int maxTimeOffset, int nHiddenNodes) {
+      int targetVariableIndex = dataset.GetVariableIndex(targetVariable);
+      List<int> allowedColumns = CalculateAllowedColumns(dataset, targetVariableIndex, inputVariables.Select(x => dataset.GetVariableIndex(x)), start, end);
+      List<int> allowedRows = CalculateAllowedRows(dataset, targetVariableIndex, allowedColumns, start, end, minTimeOffset, maxTimeOffset);
+
+      double[,] inputMatrix = PrepareInputMatrix(dataset, allowedColumns, allowedRows, minTimeOffset, maxTimeOffset);
+      double[] targetVector = PrepareTargetVector(dataset, targetVariableIndex, allowedRows);
+
+      var perceptron = TrainPerceptron(inputMatrix, targetVector, nHiddenNodes);
+      return new MultiLayerPerceptron(perceptron, inputVariables, minTimeOffset, maxTimeOffset);
+    }
+
+
+
+    private static alglib.mlpbase.multilayerperceptron TrainPerceptron(double[,] inputMatrix, double[] targetVector, int nHiddenNodes) {
+      int retVal = 0;
+      int n = targetVector.Length;
+      int p = inputMatrix.GetLength(1);
+      alglib.mlpbase.multilayerperceptron perceptron = new alglib.mlpbase.multilayerperceptron();
+      alglib.mlpbase.mlpcreate1(p - 1, nHiddenNodes, 1, ref perceptron);
+      alglib.mlptrain.mlpreport report = new alglib.mlptrain.mlpreport();
+      double[,] dataset = new double[n, p];
+      for (int row = 0; row < n; row++) {
+        for (int column = 0; column < p - 1; column++) {
+          dataset[row, column] = inputMatrix[row, column];
+        }
+        dataset[row, p - 1] = targetVector[row];
+      }
+      alglib.mlptrain.mlptrainlbfgs(ref perceptron, ref dataset, n, 0.001, 2, 0.01, 0, ref retVal, ref report);
+      if (retVal != 2) throw new ArgumentException("Error in training of multi layer perceptron");
+      return perceptron;
+    }
+
+    //returns list of valid row indexes (rows without NaN values)
+    private static List<int> CalculateAllowedRows(Dataset dataset, int targetVariable, IList<int> allowedColumns, int start, int end, int minTimeOffset, int maxTimeOffset) {
+      List<int> allowedRows = new List<int>();
+      bool add;
+      for (int row = start; row < end; row++) {
+        add = true;
+        for (int colIndex = 0; colIndex < allowedColumns.Count && add == true; colIndex++) {
+          for (int timeOffset = minTimeOffset; timeOffset <= maxTimeOffset; timeOffset++) {
+            if (
+              row + timeOffset < 0 ||
+              row + timeOffset > dataset.Rows ||
+              double.IsNaN(dataset.GetValue(row + timeOffset, allowedColumns[colIndex])) ||
+              double.IsInfinity(dataset.GetValue(row + timeOffset, allowedColumns[colIndex])) ||
+              double.IsNaN(dataset.GetValue(row + timeOffset, targetVariable))) {
+              add = false;
+            }
+          }
+        }
+        if (add)
+          allowedRows.Add(row);
+        add = true;
+      }
+      return allowedRows;
+    }
+
+    //returns list of valid column indexes (columns which contain max. 10% NaN (or infinity) and contain at least two different values)
+    private static List<int> CalculateAllowedColumns(Dataset dataset, int targetVariable, IEnumerable<int> inputVariables, int start, int end) {
+      List<int> allowedColumns = new List<int>();
+      double n = end - start;
+      foreach (int inputVariable in inputVariables) {// = 0; i < dataset.Columns; i++) {
+        double nanRatio = dataset.CountMissingValues(inputVariable, start, end) / n;
+        if (inputVariable != targetVariable && nanRatio < 0.1 && dataset.GetRange(inputVariable, start, end) > 0.0) {
+          allowedColumns.Add(inputVariable);
+        }
+      }
+      return allowedColumns;
+    }
+
+    private static double[,] PrepareInputMatrix(Dataset dataset, List<int> allowedColumns, List<int> allowedRows, int minTimeOffset, int maxTimeOffset) {
+      int rowCount = allowedRows.Count;
+      int timeOffsetRange = (maxTimeOffset - minTimeOffset + 1);
+      double[,] matrix = new double[rowCount, (allowedColumns.Count * timeOffsetRange) + 1];
+      for (int row = 0; row < allowedRows.Count; row++)
+        for (int col = 0; col < allowedColumns.Count; col++) {
+          for (int timeOffset = minTimeOffset; timeOffset <= maxTimeOffset; timeOffset++)
+            matrix[row, (col * timeOffsetRange) + (timeOffset - minTimeOffset)] = dataset.GetValue(allowedRows[row] + timeOffset, allowedColumns[col]);
+        }
+      //add constant 1.0 in last column
+      for (int i = 0; i < rowCount; i++)
+        matrix[i, allowedColumns.Count * timeOffsetRange] = 1.0;
+      return matrix;
+    }
+
+    private static double[] PrepareTargetVector(Dataset dataset, int targetVariable, List<int> allowedRows) {
+      int rowCount = allowedRows.Count;
+      double[] targetVector = new double[rowCount];
+      double[] samples = dataset.Samples;
+      for (int row = 0; row < rowCount; row++) {
+        targetVector[row] = dataset.GetValue(allowedRows[row], targetVariable);
+      }
+      return targetVector;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/Predictor.cs
===================================================================
--- trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/Predictor.cs	(revision 2562)
+++ trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/Predictor.cs	(revision 2562)
@@ -0,0 +1,85 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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 HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Modeling;
+using System;
+using System.Xml;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.ArtificialNeuralNetworks {
+  public class Predictor : PredictorBase {
+    private MultiLayerPerceptron perceptron;
+    public Predictor() : base() { } // for persistence
+    public Predictor(MultiLayerPerceptron perceptron, double lowerPredictionLimit, double upperPredictionLimit)
+      : base(lowerPredictionLimit, upperPredictionLimit) {
+      this.perceptron = perceptron;
+    }
+
+    public override double[] Predict(Dataset input, int start, int end) {
+
+      if (start < 0 || end <= start) throw new ArgumentException("start must be larger than zero and strictly smaller than end");
+      if (end > input.Rows) throw new ArgumentOutOfRangeException("number of rows in input is smaller then end");
+      double[] result = new double[end - start];
+      for (int i = 0; i < result.Length; i++) {
+        try {
+          double[] output = new double[1];
+          double[] inputRow = new double[input.Columns - 1];
+          for (int c = 1; c < inputRow.Length; c++) {
+            inputRow[c - 1] = input.GetValue(i + start, c);
+          }
+          alglib.mlpbase.multilayerperceptron p = perceptron.Perceptron;
+          alglib.mlpbase.mlpprocess(ref p, ref inputRow, ref output);
+          perceptron.Perceptron = p;
+          result[i] = Math.Max(Math.Min(output[0], UpperPredictionLimit), LowerPredictionLimit);
+        }
+        catch (ArgumentException) {
+          result[i] = double.NaN;
+        }
+      }
+      return result;
+    }
+
+    public override IEnumerable<string> GetInputVariables() {
+      return perceptron.InputVariables;
+    }
+
+
+    public override object Clone(IDictionary<Guid, object> clonedObjects) {
+      Predictor clone = (Predictor)base.Clone(clonedObjects);
+      clone.perceptron = (MultiLayerPerceptron)Auxiliary.Clone(perceptron, clonedObjects);
+      return clone;
+    }
+
+    public override System.Xml.XmlNode GetXmlNode(string name, System.Xml.XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
+      node.AppendChild(PersistenceManager.Persist("Perceptron", perceptron, document, persistedObjects));
+      return node;
+    }
+
+    public override void Populate(System.Xml.XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
+      base.Populate(node, restoredObjects);
+      perceptron = (MultiLayerPerceptron)PersistenceManager.Restore(node.SelectSingleNode("Perceptron"), restoredObjects);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/PredictorBuilder.cs
===================================================================
--- trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/PredictorBuilder.cs	(revision 2562)
+++ trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/PredictorBuilder.cs	(revision 2562)
@@ -0,0 +1,74 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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 System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Modeling;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.ArtificialNeuralNetworks {
+  public class PredictorBuilder : OperatorBase {
+    public PredictorBuilder()
+      : base() {
+      AddVariableInfo(new VariableInfo("MultiLayerPerceptron", "MultiLayerPerceptron", typeof(MultiLayerPerceptron), VariableKind.In));
+      AddVariableInfo(new VariableInfo("PunishmentFactor", "The punishment factor limits the estimated values to a certain range", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("Dataset", "The dataset", typeof(Dataset), VariableKind.In));
+      AddVariableInfo(new VariableInfo("TrainingSamplesStart", "Start index of training set", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("TrainingSamplesEnd", "End index of training set", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("TargetVariable", "Name of the target variable", typeof(StringData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("Predictor", "The predictor combines the function tree and the evaluator and can be used to generate estimated values", typeof(IPredictor), VariableKind.New));
+    }
+
+    public override string Description {
+      get { return "TODO"; }
+    }
+
+    public override IOperation Apply(IScope scope) {
+      MultiLayerPerceptron model = GetVariableValue<MultiLayerPerceptron>("MultiLayerPerceptron", scope, true);
+      double punishmentFactor = GetVariableValue<DoubleData>("PunishmentFactor", scope, true).Data;
+      Dataset dataset = GetVariableValue<Dataset>("Dataset", scope, true);
+      int start = GetVariableValue<IntData>("TrainingSamplesStart", scope, true).Data;
+      int end = GetVariableValue<IntData>("TrainingSamplesEnd", scope, true).Data;
+      string targetVariable = GetVariableValue<StringData>("TargetVariable", scope, true).Data;
+      IPredictor predictor = CreatePredictor(model, punishmentFactor, dataset, targetVariable, start, end);
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("Predictor"), predictor));
+      return null;
+    }
+
+    public static IPredictor CreatePredictor(MultiLayerPerceptron perceptron, double punishmentFactor,
+      Dataset dataset, int targetVariable, int start, int end) {
+      double mean = dataset.GetMean(targetVariable, start, end);
+      double range = dataset.GetRange(targetVariable, start, end);
+      double minEstimatedValue = mean - punishmentFactor * range;
+      double maxEstimatedValue = mean + punishmentFactor * range;
+      return new Predictor(perceptron, minEstimatedValue, maxEstimatedValue);
+    }
+
+    public static IPredictor CreatePredictor(MultiLayerPerceptron perceptron, double punishmentFactor,
+      Dataset dataset, string targetVariable, int start, int end) {
+      return CreatePredictor(perceptron, punishmentFactor, dataset, dataset.GetVariableIndex(targetVariable), start, end);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/Properties/AssemblyInfo.frame
===================================================================
--- trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/Properties/AssemblyInfo.frame	(revision 2562)
+++ trunk/sources/HeuristicLab.ArtificialNeuralNetworks/3.2/Properties/AssemblyInfo.frame	(revision 2562)
@@ -0,0 +1,58 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using HeuristicLab.PluginInfrastructure;
+
+// 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.ArtificialNeuralNetworks")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2009 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("863021a4-3cde-48be-8af6-dac1077f5fb5")]
+
+// 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 Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.2.0.$WCREV$")]
+[assembly: AssemblyFileVersion("3.2.0.$WCREV$")]
+[assembly: AssemblyBuildDate("$WCNOW$")]
