Index: branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 15885)
+++ branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 15938)
@@ -231,4 +231,5 @@
     <Compile Include="Implementation\Transformations\LinearTransformation.cs" />
     <Compile Include="Implementation\Transformations\LogarithmTransformation.cs" />
+    <Compile Include="Implementation\Transformations\RescaleTransformation.cs" />
     <Compile Include="Implementation\Transformations\Transformation.cs" />
     <Compile Include="Implementation\Transformations\ZNormalizationTransformation.cs" />
Index: branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs
===================================================================
--- branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs	(revision 15885)
+++ branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs	(revision 15938)
@@ -30,27 +30,27 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [Item("Linear", "Linear transformation x' = slope * x + intercept")]
+  [Item("Linear", "Linear transformation x' = Scale * x + Offset")]
   [StorableClass]
   public class LinearTransformation : Transformation<double> {
 
     #region Parameters
-    private FixedValueParameter<DoubleValue> SlopeParameter {
-      get { return (FixedValueParameter<DoubleValue>)Parameters["Slope"]; }
+    private FixedValueParameter<DoubleValue> ScaleParameter {
+      get { return (FixedValueParameter<DoubleValue>)Parameters["Scale"]; }
     }
 
-    private FixedValueParameter<DoubleValue> InterceptParameter {
-      get { return (FixedValueParameter<DoubleValue>)Parameters["Intercept"]; }
+    private FixedValueParameter<DoubleValue> OffsetParameter {
+      get { return (FixedValueParameter<DoubleValue>)Parameters["Offset"]; }
     }
     #endregion
 
     #region Properties
-    public double Slope {
-      get { return SlopeParameter.Value.Value; }
-      set { SlopeParameter.Value.Value = value; }
+    public double Scale {
+      get { return ScaleParameter.Value.Value; }
+      set { ScaleParameter.Value.Value = value; }
     }
 
-    public double Intercept {
-      get { return InterceptParameter.Value.Value; }
-      set { InterceptParameter.Value.Value = value; }
+    public double Offset {
+      get { return OffsetParameter.Value.Value; }
+      set { OffsetParameter.Value.Value = value; }
     }
     #endregion
@@ -59,6 +59,6 @@
     public LinearTransformation()
       : base() {
-      Parameters.Add(new FixedValueParameter<DoubleValue>("Slope", "Slope (multiplicative factor)", new DoubleValue(1.0)));
-      Parameters.Add(new FixedValueParameter<DoubleValue>("Intercept", "Intercept (additive factor)", new DoubleValue(0.0)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Scale", "Multiplicative factor (Slope)", new DoubleValue(1.0)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Offset", "Additive factor (Intercept)", new DoubleValue(0.0)));
     }
 
@@ -77,24 +77,24 @@
 
     public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      return Apply(data, Slope, Intercept);
+      return Apply(data, Scale, Offset);
     }
 
     public override IEnumerable<double> InverseApply(IEnumerable<double> data) {
-      return InverseApply(data, Slope, Intercept);
+      return InverseApply(data, Scale, Offset);
     }
 
 
-    public static IEnumerable<double> Apply(IEnumerable<double> data, double slope = 1.0, double intercept = 0.0) {
-      if (slope.IsAlmost(0.0))
-        throw new InvalidOperationException($"Cannot transform with a {nameof(slope)} of zero because inverse transformation would be invalid.");
+    public static IEnumerable<double> Apply(IEnumerable<double> data, double scale = 1.0, double offset = 0.0) {
+      if (scale.IsAlmost(0.0))
+        throw new InvalidOperationException($"Cannot transform with a {nameof(scale)} of zero because inverse transformation would be invalid.");
 
-      return data.Select(x => slope * x + intercept);
+      return data.Select(x => scale * x + offset);
     }
 
-    public static IEnumerable<double> InverseApply(IEnumerable<double> data, double slope = 1.0, double intercept = 0.0) {
-      if (slope.IsAlmost(0.0))
-        throw new InvalidOperationException($"Cannot inverse transform with a {nameof(slope)} of zero.");
+    public static IEnumerable<double> InverseApply(IEnumerable<double> data, double scale = 1.0, double offset = 0.0) {
+      if (scale.IsAlmost(0.0))
+        throw new InvalidOperationException($"Cannot inverse transform with a {nameof(scale)} of zero.");
 
-      return data.Select(x => (x - intercept) / slope);
+      return data.Select(x => (x - offset) / scale);
     }
   }
Index: branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmTransformation.cs
===================================================================
--- branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmTransformation.cs	(revision 15885)
+++ branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmTransformation.cs	(revision 15938)
@@ -37,4 +37,7 @@
       get { return (FixedValueParameter<DoubleValue>)Parameters["Base"]; }
     }
+    private FixedValueParameter<DoubleValue> OffsetParameter {
+      get { return (FixedValueParameter<DoubleValue>)Parameters["Offset"]; }
+    }
     #endregion
 
@@ -44,4 +47,8 @@
       set { BaseParameter.Value.Value = value; }
     }
+    public double Offset {
+      get { return OffsetParameter.Value.Value; }
+      set { OffsetParameter.Value.Value = value; }
+    }
     #endregion
 
@@ -50,4 +57,5 @@
       : base() {
       Parameters.Add(new FixedValueParameter<DoubleValue>("Base", "Base the logarithm", new DoubleValue(Math.E)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Offset", "Offset before the logarithm", new DoubleValue(0.0)));
     }
 
@@ -66,5 +74,5 @@
 
     public override bool Check(IEnumerable<double> data, out string errorMessage) {
-      if (data.Any(x => x <= 0)) {
+      if (data.Any(x => x + Offset <= 0)) {
         errorMessage = "Log is not available for zero or negative values";
         return false;
@@ -74,18 +82,18 @@
 
     public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      return Apply(data, Base);
+      return Apply(data, Base, Offset);
     }
 
     public override IEnumerable<double> InverseApply(IEnumerable<double> data) {
-      return InverseApply(data, Base);
+      return InverseApply(data, Base, Offset);
     }
 
 
-    public static IEnumerable<double> Apply(IEnumerable<double> data, double @base = Math.E) {
-      return data.Select(x => Math.Log(x, @base));
+    public static IEnumerable<double> Apply(IEnumerable<double> data, double @base = Math.E, double offset = 0.0) {
+      return data.Select(x => Math.Log(x + offset, @base));
     }
 
-    public static IEnumerable<double> InverseApply(IEnumerable<double> data, double @base = Math.E) {
-      return ExponentialTransformation.Apply(data, @base);
+    public static IEnumerable<double> InverseApply(IEnumerable<double> data, double @base = Math.E, double offset = 0.0) {
+      return ExponentialTransformation.InverseApply(data, @base).Select(x => x - offset);
     }
   }
Index: branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/RescaleTransformation.cs
===================================================================
--- branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/RescaleTransformation.cs	(revision 15938)
+++ branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/RescaleTransformation.cs	(revision 15938)
@@ -0,0 +1,143 @@
+﻿// #region License Information
+// /* HeuristicLab
+//  * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Rescale", "Rescale the data to a given range (e.g. [0-1]).")]
+  [StorableClass]
+  public class RescaleTransformation : Transformation<double> {
+
+    #region Parameters
+    private IFixedValueParameter<DoubleRange> TargetRangeParameter {
+      get { return (IFixedValueParameter<DoubleRange>)Parameters["Target Range"]; }
+    }
+    private IFixedValueParameter<DoubleRange> OriginalRangeParameter {
+      get { return (IFixedValueParameter<DoubleRange>)Parameters["Original Range"]; }
+    }
+    #endregion
+
+    #region Properties
+    public double TargetMin {
+      get { return TargetRangeParameter.Value.Start; }
+      set { TargetRangeParameter.Value.Start = value; }
+    }
+    public double TargetMax {
+      get { return TargetRangeParameter.Value.End; }
+      set { TargetRangeParameter.Value.End = value; }
+    }
+    public double OriginalMin {
+      get { return OriginalRangeParameter.Value.Start; }
+      private set { OriginalRangeParameter.Value.Start = value; }
+    }
+    public double OriginalMax {
+      get { return OriginalRangeParameter.Value.End; }
+      private set { OriginalRangeParameter.Value.End = value; }
+    }
+    #endregion
+
+    #region Constructor, Cloning & Persistence
+    public RescaleTransformation()
+      : base() {
+      Parameters.Add(new FixedValueParameter<DoubleRange>("Target Range", new DoubleRange(0.0, 1.0)));
+      Parameters.Add(new FixedValueParameter<DoubleRange>("Original Range", new DoubleRange(double.NaN, double.NaN)) { Hidden = true });
+    }
+
+    protected RescaleTransformation(RescaleTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RescaleTransformation(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected RescaleTransformation(bool deserializing)
+      : base(deserializing) {
+    }
+    #endregion
+
+    public override bool Check(IEnumerable<double> data, out string errorMessage) {
+      if (data.StandardDeviationPop().IsAlmost(0.0)) {
+        errorMessage = "Rescaling cannot be applied for data with a standard deviation of zero.";
+        return false;
+      }
+      return base.Check(data, out errorMessage);
+    }
+
+    public override void Configure(IEnumerable<double> data) {
+      Configure(data, out double originalMin, out double originalMax);
+      OriginalMin = originalMin;
+      OriginalMax = originalMax;
+      base.Configure(data);
+    }
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      if (double.IsNaN(OriginalMin) || double.IsNaN(OriginalMax))
+        throw new InvalidOperationException("Transformation is not configured");
+
+      return Apply(data, TargetMin, TargetMax, OriginalMin, OriginalMax);
+    }
+
+    public override IEnumerable<double> InverseApply(IEnumerable<double> data) {
+      if (double.IsNaN(OriginalMin) || double.IsNaN(OriginalMax))
+        throw new InvalidOperationException("Transformation is not configured");
+
+      return InverseApply(data, TargetMin, TargetMax, OriginalMin, OriginalMax);
+    }
+
+
+    public static void Configure(IEnumerable<double> data, out double originalMin, out double originalMax) {
+      originalMin = data.Min();
+      originalMax = data.Max();
+    }
+
+    public static IEnumerable<double> Apply(IEnumerable<double> data, double targetMin, double targetMax, double originalMin = double.NaN, double originalMax = double.NaN) {
+      if (double.IsNaN(originalMin)) originalMin = data.Min();
+      if (double.IsNaN(originalMax)) originalMax = data.Max();
+
+      GetLinearTransformationParameters(targetMin, targetMax, originalMin, originalMax, out double scale, out double offset);
+
+      return LinearTransformation.Apply(data, scale, offset);
+    }
+
+    public static IEnumerable<double> InverseApply(IEnumerable<double> data, double targetMin, double targetMax, double originalMin, double originalMax) {
+      GetLinearTransformationParameters(targetMin, targetMax, originalMin, originalMax, out double scale, out double offset);
+
+      return LinearTransformation.InverseApply(data, scale, offset);
+    }
+
+    private static void GetLinearTransformationParameters(double targetMin, double targetMax, double originalMin, double originalMax,
+        out double scale, out double offset) {
+      var originalRange = originalMax - originalMin;
+      var targetRange = targetMax - targetMin;
+
+      scale = targetRange / originalRange;
+      offset = targetMin - originalMin * scale;
+    }
+  }
+}
Index: branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisTransformationModel.cs
===================================================================
--- branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisTransformationModel.cs	(revision 15885)
+++ branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisTransformationModel.cs	(revision 15938)
@@ -26,7 +26,4 @@
     IDataAnalysisModel OriginalModel { get; }
 
-    /// <summary>
-    /// Transformations that are used on the model's inputs.
-    /// </summary>
     IEnumerable<IDataAnalysisTransformation> InputTransformations { get; }
   }
