Changeset 7099


Ignore:
Timestamp:
11/29/11 19:52:22 (8 years ago)
Author:
gkronber
Message:

#1081: merged old changesets r6802, r6807:6808, r6811, r6974, r7058 from the trunk into the TimeSeries branch to bring it to version r7096.

Location:
branches/HeuristicLab.TimeSeries
Files:
4 deleted
14 edited
18 copied

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.TimeSeries/HeuristicLab 3.3.sln

    r7097 r7099  
    8181    {E10F395F-C8A6-48AD-B470-9AA7A1F43809} = {E10F395F-C8A6-48AD-B470-9AA7A1F43809}
    8282    {B7A64A60-B538-479F-9C47-A3180C458F6C} = {B7A64A60-B538-479F-9C47-A3180C458F6C}
     83    {07486E68-1517-4B9D-A58D-A38E99AE71AB} = {07486E68-1517-4B9D-A58D-A38E99AE71AB}
    8384    {4AE3FC69-C575-42D2-BC46-0FAD5850EFC5} = {4AE3FC69-C575-42D2-BC46-0FAD5850EFC5}
    8485    {56F9106A-079F-4C61-92F6-86A84C2D84B7} = {56F9106A-079F-4C61-92F6-86A84C2D84B7}
     
    9293    {70DFD984-B1D9-46FE-8EB7-4DE92D71A9FC} = {70DFD984-B1D9-46FE-8EB7-4DE92D71A9FC}
    9394    {06D4A186-9319-48A0-BADE-A2058D462EEA} = {06D4A186-9319-48A0-BADE-A2058D462EEA}
     95    {5B9B9E8C-2706-43C2-80B8-A08341E431F7} = {5B9B9E8C-2706-43C2-80B8-A08341E431F7}
    9496    {997F018D-AEA2-4F21-9301-82FAF6A5612D} = {997F018D-AEA2-4F21-9301-82FAF6A5612D}
    9597    {D767C38D-8014-46B0-9A32-03A3AECCE34A} = {D767C38D-8014-46B0-9A32-03A3AECCE34A}
     
    114116    {66D249C3-A01D-42A8-82A2-919BC8EC3D83} = {66D249C3-A01D-42A8-82A2-919BC8EC3D83}
    115117    {E4CFB0C3-0589-4893-B38E-8BEDF885C765} = {E4CFB0C3-0589-4893-B38E-8BEDF885C765}
     118    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962} = {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}
    116119    {79271BC8-4446-40E2-BB89-9BE4E17174FE} = {79271BC8-4446-40E2-BB89-9BE4E17174FE}
     120    {02766ECC-D0F5-4115-9ECA-47409167B638} = {02766ECC-D0F5-4115-9ECA-47409167B638}
    117121    {7A2531CE-3F7C-4F13-BCCA-ED6DC27A7086} = {7A2531CE-3F7C-4F13-BCCA-ED6DC27A7086}
    118122    {102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B} = {102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B}
     
    316320EndProject
    317321Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.Benchmarks.Views-3.3", "HeuristicLab.Algorithms.Benchmarks.Views\3.3\HeuristicLab.Algorithms.Benchmarks.Views-3.3.csproj", "{3C906172-E044-4DF0-B4FD-AA21192D5D3E}"
     322EndProject
     323Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4", "HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj", "{07486E68-1517-4B9D-A58D-A38E99AE71AB}"
     324EndProject
     325Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4", "HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj", "{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}"
    318326EndProject
    319327Global
     
    15241532    {3C906172-E044-4DF0-B4FD-AA21192D5D3E}.Release|x86.ActiveCfg = Release|x86
    15251533    {3C906172-E044-4DF0-B4FD-AA21192D5D3E}.Release|x86.Build.0 = Release|x86
     1534    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
     1535    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
     1536    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|x64.ActiveCfg = Debug|x64
     1537    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|x64.Build.0 = Debug|x64
     1538    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|x86.ActiveCfg = Debug|x86
     1539    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|x86.Build.0 = Debug|x86
     1540    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
     1541    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|Any CPU.Build.0 = Release|Any CPU
     1542    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|x64.ActiveCfg = Release|x64
     1543    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|x64.Build.0 = Release|x64
     1544    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|x86.ActiveCfg = Release|x86
     1545    {07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|x86.Build.0 = Release|x86
     1546    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
     1547    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|Any CPU.Build.0 = Debug|Any CPU
     1548    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|x64.ActiveCfg = Debug|x64
     1549    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|x64.Build.0 = Debug|x64
     1550    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|x86.ActiveCfg = Debug|x86
     1551    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|x86.Build.0 = Debug|x86
     1552    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|Any CPU.ActiveCfg = Release|Any CPU
     1553    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|Any CPU.Build.0 = Release|Any CPU
     1554    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|x64.ActiveCfg = Release|x64
     1555    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|x64.Build.0 = Release|x64
     1556    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|x86.ActiveCfg = Release|x86
     1557    {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|x86.Build.0 = Release|x86
    15261558  EndGlobalSection
    15271559  GlobalSection(SolutionProperties) = preSolution
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj

    r7097 r7099  
    144144    </Compile>
    145145    <Compile Include="Linear\AlglibUtil.cs" />
     146    <Compile Include="Linear\LinearTimeSeriesPrognosis.cs" />
    146147    <Compile Include="Linear\LinearDiscriminantAnalysis.cs" />
    147148    <Compile Include="Linear\LinearRegression.cs">
     
    247248      <Private>False</Private>
    248249    </ProjectReference>
     250    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj">
     251      <Project>{07486E68-1517-4B9D-A58D-A38E99AE71AB}</Project>
     252      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4</Name>
     253      <Private>False</Private>
     254    </ProjectReference>
    249255    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj">
    250256      <Project>{3D28463F-EC96-4D82-AFEE-38BE91A0CA00}</Project>
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/AlglibUtil.cs

    r7097 r7099  
    2727  public static class AlglibUtil {
    2828    public static double[,] PrepareInputMatrix(Dataset dataset, IEnumerable<string> variables, IEnumerable<int> rows) {
    29       List<string> variablesList = variables.ToList();
     29      return PrepareInputMatrix(dataset, variables, rows, new int[] { 0 });
     30    }
     31
     32    public static double[,] PrepareInputMatrix(Dataset dataset, IEnumerable<string> variables, IEnumerable<int> rows, IEnumerable<int> lags) {
     33      int maxLag = lags.Max();
     34
     35      // drop last variable (target variable)
     36      List<string> inputVariablesList = variables
     37        .Reverse()
     38        .Skip(1)
     39        .Reverse()
     40        .ToList();
     41      string targetVariable = variables.Last();
    3042      List<int> rowsList = rows.ToList();
    31 
    32       double[,] matrix = new double[rowsList.Count, variablesList.Count];
     43      int nRows = rowsList.Count - maxLag;
     44      double[,] matrix = new double[nRows, inputVariablesList.Count * lags.Count() + 1];
    3345
    3446      int col = 0;
    35       foreach (string column in variables) {
    36         var values = dataset.GetDoubleValues(column, rows);
    37         int row = 0;
    38         foreach (var value in values) {
    39           matrix[row, col] = value;
    40           row++;
     47      int row = 0;
     48      // input variables
     49      foreach (int lag in lags) {
     50        foreach (string column in inputVariablesList) {
     51          var values = dataset.GetDoubleValues(column, rows.Select(x => x - lag).Take(nRows));
     52          row = 0;
     53          foreach (var value in values) {
     54            if (row >= 0) {
     55              matrix[row, col] = value;
     56            }
     57            row++;
     58          }
     59          col++;
    4160        }
    42         col++;
    4361      }
    44 
     62      // target variable
     63      row = 0;
     64      foreach (var value in dataset.GetDoubleValues(targetVariable, rows).Take(nRows)) {
     65        matrix[row, col] = value;
     66        row++;
     67      }
    4568      return matrix;
    4669    }
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorRegression.cs

    r7097 r7099  
    143143      parameter.Probability = false;
    144144
    145 
    146145      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(dataset, targetVariable, allowedInputVariables, rows);
    147146      SVM.RangeTransform rangeTransform = SVM.RangeTransform.Compute(problem);
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.cs

    r7097 r7099  
    6767      }
    6868
     69      var laggedVariables = Content.Model.SymbolicExpressionTree.IterateNodesPostfix()
     70        .OfType<LaggedVariableTreeNode>()
     71        .Select(n => n.Lag)
     72        .Where(l => l < 0);
     73      if (laggedVariables.Any()) throw new NotSupportedException("The symbolic regression solution contains lagged variables.");
     74
    6975      //check inputVariables used in the symbolic regression model
    7076      var usedVariables =
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj

    r6807 r7099  
    4141    <DebugType>full</DebugType>
    4242    <Optimize>false</Optimize>
    43     <OutputPath>bin\Debug\</OutputPath>
     43    <OutputPath>../../bin/</OutputPath>
    4444    <DefineConstants>DEBUG;TRACE</DefineConstants>
    4545    <ErrorReport>prompt</ErrorReport>
     
    5858  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
    5959    <DebugSymbols>true</DebugSymbols>
    60     <OutputPath>bin\x64\Debug\</OutputPath>
     60    <OutputPath>../../bin/</OutputPath>
    6161    <DefineConstants>DEBUG;TRACE</DefineConstants>
    6262    <DebugType>full</DebugType>
     
    6666  </PropertyGroup>
    6767  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
    68     <OutputPath>bin\x64\Release\</OutputPath>
     68    <OutputPath>../../bin/</OutputPath>
    6969    <DefineConstants>TRACE</DefineConstants>
    7070    <Optimize>true</Optimize>
     
    7676  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    7777    <DebugSymbols>true</DebugSymbols>
    78     <OutputPath>bin\x86\Debug\</OutputPath>
     78    <OutputPath>../../bin/</OutputPath>
    7979    <DefineConstants>DEBUG;TRACE</DefineConstants>
    8080    <DebugType>full</DebugType>
     
    8484  </PropertyGroup>
    8585  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    86     <OutputPath>bin\x86\Release\</OutputPath>
     86    <OutputPath>../../bin/</OutputPath>
    8787    <DefineConstants>TRACE</DefineConstants>
    8888    <Optimize>true</Optimize>
     
    110110  </ItemGroup>
    111111  <ItemGroup>
    112     <Compile Include="HeuristicLabProblemsDataAnalysisSymbolicTimeSeriesPrognosisViewsPlugin.cs" />
     112    <Compile Include="Plugin.cs" />
    113113    <Compile Include="SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs">
    114114      <SubType>UserControl</SubType>
     
    124124    </Compile>
    125125    <None Include="HeuristicLab.snk" />
    126     <None Include="HeuristicLabProblemsDataAnalysisSymbolicTimeSeriesPrognosisViewsPlugin.cs.frame" />
    127     <None Include="Properties\AssemblyInfo.frame" />
     126    <None Include="Plugin.cs.frame" />
    128127    <Compile Include="InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs">
    129128      <SubType>UserControl</SubType>
     
    133132    </Compile>
    134133    <Compile Include="Properties\AssemblyInfo.cs" />
     134    <None Include="Properties\AssemblyInfo.cs.frame" />
    135135  </ItemGroup>
    136136  <ItemGroup>
     
    256256
    257257call PreBuildEvent.cmd
    258 SubWCRev "%25ProjectDir%25\" "%25ProjectDir%25\HeuristicLabProblemsDataAnalysisSymbolicTimeSeriesPrognosisViewsPlugin.cs.frame" "%25ProjectDir%25\HeuristicLabProblemsDataAnalysisSymbolicTimeSeriesPrognosisViewsPlugin.cs"</PreBuildEvent>
     258</PreBuildEvent>
    259259  </PropertyGroup>
    260260</Project>
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj

    r6802 r7099  
    4141    <DebugType>full</DebugType>
    4242    <Optimize>false</Optimize>
    43     <OutputPath>bin\Debug\</OutputPath>
     43    <OutputPath>../../bin/</OutputPath>
    4444    <DefineConstants>DEBUG;TRACE</DefineConstants>
    4545    <ErrorReport>prompt</ErrorReport>
     
    5050    <DebugType>pdbonly</DebugType>
    5151    <Optimize>true</Optimize>
    52     <OutputPath>bin\Release\</OutputPath>
     52    <OutputPath>../../bin/</OutputPath>
    5353    <DefineConstants>TRACE</DefineConstants>
    5454    <ErrorReport>prompt</ErrorReport>
     
    5858  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
    5959    <DebugSymbols>true</DebugSymbols>
    60     <OutputPath>bin\x64\Debug\</OutputPath>
     60    <OutputPath>../../bin/</OutputPath>
    6161    <DefineConstants>DEBUG;TRACE</DefineConstants>
    6262    <DebugType>full</DebugType>
     
    6666  </PropertyGroup>
    6767  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
    68     <OutputPath>bin\x64\Release\</OutputPath>
     68    <OutputPath>../../bin/</OutputPath>
    6969    <DefineConstants>TRACE</DefineConstants>
    7070    <Optimize>true</Optimize>
     
    7676  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    7777    <DebugSymbols>true</DebugSymbols>
    78     <OutputPath>bin\x86\Debug\</OutputPath>
     78    <OutputPath>../../bin/</OutputPath>
    7979    <DefineConstants>DEBUG;TRACE</DefineConstants>
    8080    <DebugType>full</DebugType>
     
    8484  </PropertyGroup>
    8585  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    86     <OutputPath>bin\x86\Release\</OutputPath>
     86    <OutputPath>../../bin/</OutputPath>
    8787    <DefineConstants>TRACE</DefineConstants>
    8888    <Optimize>true</Optimize>
     
    9393  </PropertyGroup>
    9494  <ItemGroup>
     95    <Reference Include="ALGLIB-3.1.0, Version=3.1.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     96    <Reference Include="HeuristicLab.ALGLIB-3.1.0, Version=3.1.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
    9597    <Reference Include="System" />
    9698    <Reference Include="System.Core">
     
    108110  </ItemGroup>
    109111  <ItemGroup>
    110     <Compile Include="HeuristicLabProblemsDataAnalysisSymbolicTimeSeriesPrognosisPlugin.cs" />
    111112    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisEvaluator.cs" />
    112113    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisModel.cs" />
    113114    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs" />
    114115    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisSolution.cs" />
     116    <Compile Include="Plugin.cs" />
    115117    <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs" />
    116118    <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs" />
     
    123125    <Compile Include="SymbolicTimeSeriesPrognosisSolution.cs" />
    124126    <None Include="HeuristicLab.snk" />
    125     <None Include="HeuristicLabProblemsDataAnalysisSymbolicTimeSeriesPrognosisPlugin.cs.frame" />
    126     <None Include="Properties\AssemblyInfo.frame" />
     127    <None Include="Plugin.cs.frame" />
    127128    <Compile Include="Properties\AssemblyInfo.cs" />
     129    <None Include="Properties\AssemblyInfo.cs.frame" />
    128130  </ItemGroup>
    129131  <ItemGroup>
     
    151153      <Project>{06D4A186-9319-48A0-BADE-A2058D462EEA}</Project>
    152154      <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4</Name>
    153     </ProjectReference>
    154     <ProjectReference Include="..\..\HeuristicLab.ExtLibs\HeuristicLab.ALGLIB\3.1.0\ALGLIB-3.1.0\ALGLIB-3.1.0.csproj">
    155       <Project>{FC841674-62A7-4055-BE91-E41944B6C606}</Project>
    156       <Name>ALGLIB-3.1.0</Name>
    157     </ProjectReference>
    158     <ProjectReference Include="..\..\HeuristicLab.ExtLibs\HeuristicLab.ALGLIB\3.1.0\HeuristicLab.ALGLIB-3.1.0\HeuristicLab.ALGLIB-3.1.0.csproj">
    159       <Project>{DE69A359-A5B8-4D3D-BA8D-D5780D7F96D6}</Project>
    160       <Name>HeuristicLab.ALGLIB-3.1.0 %28HeuristicLab.ExtLibs\HeuristicLab.ALGLIB\HeuristicLab.ALGLIB-3.1.0\HeuristicLab.ALGLIB-3.1.0%29</Name>
    161155    </ProjectReference>
    162156    <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
     
    222216
    223217call PreBuildEvent.cmd
    224 SubWCRev "%25ProjectDir%25\" "%25ProjectDir%25\HeuristicLabProblemsDataAnalysisSymbolicTimeSeriesPrognosisPlugin.cs.frame" "%25ProjectDir%25\HeuristicLabProblemsDataAnalysisSymbolicTimeSeriesPrognosisPlugin.cs"</PreBuildEvent>
     218</PreBuildEvent>
    225219  </PropertyGroup>
    226220</Project>
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs

    r6802 r7099  
    6262      MaximumSymbolicExpressionTreeLength.Value = InitialMaximumTreeLength;
    6363
     64      SymbolicExpressionTreeGrammarParameter.ValueChanged += (o, e) => ConfigureGrammarSymbols();
     65
     66      ConfigureGrammarSymbols();
     67
    6468      InitializeOperators();
    6569      UpdateEstimationLimits();
     70    }
     71   
     72    private void ConfigureGrammarSymbols() {
     73      var grammar = SymbolicExpressionTreeGrammar as TypeCoherentExpressionGrammar;
     74      if (grammar != null) grammar.ConfigureAsDefaultTimeSeriesPrognosisGrammar();
    6675    }
    6776
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs

    r6802 r7099  
    8686      if (startNode.GetSubtree(0).Symbol is Addition) {
    8787        var addNode = startNode.GetSubtree(0);
    88         if (addNode.SubtreesCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication && addNode.GetSubtree(1).Symbol is Constant) {
     88        if (addNode.SubtreeCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication && addNode.GetSubtree(1).Symbol is Constant) {
    8989          alphaTreeNode = addNode.GetSubtree(1) as ConstantTreeNode;
    9090          var mulNode = addNode.GetSubtree(0);
    91           if (mulNode.SubtreesCount == 2 && mulNode.GetSubtree(1).Symbol is Constant) {
     91          if (mulNode.SubtreeCount == 2 && mulNode.GetSubtree(1).Symbol is Constant) {
    9292            betaTreeNode = mulNode.GetSubtree(1) as ConstantTreeNode;
    9393          }
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs

    r7097 r7099  
    194194      Symbols.Where(s => s.Name == TimeSeriesSymbolsName).First().Enabled = false;
    195195    }
     196
     197    public void ConfigureAsDefaultTimeSeriesPrognosisGrammar() {
     198      Symbols.Where(s => s is Variable).First().Enabled = false;
     199      Symbols.Where(s => s.Name == TrigonometricFunctionsName).First().Enabled = false;
     200      Symbols.Where(s => s.Name == PowerFunctionsName).First().Enabled = false;
     201      Symbols.Where(s => s.Name == ConditionalSymbolsName).First().Enabled = false;
     202    }
    196203  }
    197204}
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj

    r7097 r7099  
    122122      <DependentUpon>ClassificationEnsembleSolutionModelView.cs</DependentUpon>
    123123    </Compile>
     124    <Compile Include="Solution Views\TimeSeriesPrognosisSolutionView.cs">
     125      <SubType>UserControl</SubType>
     126    </Compile>
     127    <Compile Include="Solution Views\TimeSeriesPrognosisSolutionView.Designer.cs">
     128      <DependentUpon>TimeSeriesPrognosisSolutionView.cs</DependentUpon>
     129    </Compile>
     130    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs">
     131      <SubType>UserControl</SubType>
     132    </Compile>
     133    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs">
     134      <DependentUpon>TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
     135    </Compile>
     136    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionLineChartView.cs">
     137      <SubType>UserControl</SubType>
     138    </Compile>
     139    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionLineChartView.Designer.cs">
     140      <DependentUpon>TimeSeriesPrognosisSolutionLineChartView.cs</DependentUpon>
     141    </Compile>
     142    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionPrognosedValuesView.cs">
     143      <SubType>UserControl</SubType>
     144    </Compile>
     145    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionPrognosedValuesView.Designer.cs">
     146      <DependentUpon>TimeSeriesPrognosisSolutionPrognosedValuesView.cs</DependentUpon>
     147    </Compile>
     148    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionScatterPlotView.cs">
     149      <SubType>UserControl</SubType>
     150    </Compile>
     151    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionScatterPlotView.Designer.cs">
     152      <DependentUpon>TimeSeriesPrognosisSolutionScatterPlotView.cs</DependentUpon>
     153    </Compile>
    124154    <Compile Include="DataAnalysisSolutionEvaluationView.cs">
    125155      <SubType>UserControl</SubType>
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj

    r7097 r7099  
    129129    </Compile>
    130130    <Compile Include="Implementation\Regression\RegressionEnsembleSolution.cs" />
     131    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisProblem.cs" />
     132    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisProblemData.cs" />
     133    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolution.cs" />
     134    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolutionBase.cs" />
    131135    <Compile Include="Interfaces\Classification\IClassificationEnsembleModel.cs">
    132136      <SubType>Code</SubType>
     
    142146    <Compile Include="Implementation\Regression\RegressionSolutionBase.cs" />
    143147    <Compile Include="OnlineCalculators\NormalizedGiniCalculator.cs" />
     148    <Compile Include="Interfaces\TimeSeriesPrognosis\IOnlineTimeSeriesCalculator.cs" />
     149    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisModel.cs" />
     150    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisProblem.cs" />
     151    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisProblemData.cs" />
     152    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisSolution.cs" />
     153    <Compile Include="OnlineCalculators\OnlineDirectionalSymmetryCalculator.cs" />
    144154    <Compile Include="OnlineCalculators\OnlineMeanAbsoluteErrorCalculator.cs" />
    145155    <Compile Include="OnlineCalculators\OnlineLinearScalingParameterCalculator.cs" />
     
    178188    <Compile Include="Implementation\Regression\RegressionSolution.cs" />
    179189    <Compile Include="Plugin.cs" />
     190    <Compile Include="OnlineCalculators\OnlineTheilsUStatisticCalculator.cs" />
     191    <Compile Include="OnlineCalculators\OnlineWeightedDirectionalSymmetryCalculator.cs" />
    180192    <Compile Include="TableFileParser.cs" />
    181193    <Compile Include="Implementation\Classification\ThresholdCalculators\AccuracyMaximizationThresholdCalculator.cs" />
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs

    r6802 r7099  
    4040    private const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
    4141    private const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
    42     private const string TrainingDirectionalSymmetryResultName = "Directional symmetry (training)";
    43     private const string TestDirectionalSymmetryResultName = "Directional symmetry (test)";
    44     private const string TrainingWeightedDirectionalSymmetryResultName = "Weighted directional symmetry (training)";
    45     private const string TestWeightedDirectionalSymmetryResultName = "Weighted directional symmetry (test)";
    46     private const string TrainingTheilsUStatisticResultName = "Theil's U (training)";
    47     private const string TestTheilsUStatisticResultName = "Theil's U (test)";
     42    private const string TrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
     43    private const string TestDirectionalSymmetryResultName = "Average directional symmetry (test)";
     44    private const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
     45    private const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
     46    private const string TrainingTheilsUStatisticResultName = "Average Theil's U (training)";
     47    private const string TestTheilsUStatisticResultName = "Average Theil's U (test)";
    4848
    4949    public new ITimeSeriesPrognosisModel Model {
     
    146146      Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the training partition", new DoubleValue()));
    147147      Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleValue()));
    148       Add(new Result(TrainingDirectionalSymmetryResultName, "The directional symmetry of the output of the model on the training partition", new DoubleValue()));
    149       Add(new Result(TestDirectionalSymmetryResultName, "The directional symmetry of the output of the model on the test partition", new DoubleValue()));
    150       Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The weighted directional symmetry of the output of the model on the training partition", new DoubleValue()));
    151       Add(new Result(TestWeightedDirectionalSymmetryResultName, "The weighted directional symmetry of the output of the model on the test partition", new DoubleValue()));
    152       Add(new Result(TrainingTheilsUStatisticResultName, "The Theil's U statistic of the output of the model on the training partition", new DoubleValue()));
    153       Add(new Result(TestTheilsUStatisticResultName, "The Theil's U statistic of the output of the model on the test partition", new DoubleValue()));
     148      Add(new Result(TrainingDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the training partition", new PercentValue()));
     149      Add(new Result(TestDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the test partition", new PercentValue()));
     150      Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the training partition", new DoubleValue()));
     151      Add(new Result(TestWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the test partition", new DoubleValue()));
     152      Add(new Result(TrainingTheilsUStatisticResultName, "The average Theil's U statistic of the forecasts of the model on the training partition", new DoubleValue()));
     153      Add(new Result(TestTheilsUStatisticResultName, "The average Theil's U statistic of the forecasts of the model on the test partition", new DoubleValue()));
    154154    }
    155155
     
    166166
    167167      OnlineCalculatorError errorState;
    168       double trainingMse = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
     168      double trainingMse = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
    169169      TrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMse : double.NaN;
    170       double testMse = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
     170      double testMse = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
    171171      TestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMse : double.NaN;
    172172
    173       double trainingMae = OnlineMeanAbsoluteErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
     173      double trainingMae = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
    174174      TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMae : double.NaN;
    175       double testMae = OnlineMeanAbsoluteErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
     175      double testMae = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
    176176      TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMae : double.NaN;
    177177
    178       double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
     178      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
    179179      TrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
    180       double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
     180      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
    181181      TestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
    182182
    183       double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
     183      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
    184184      TrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
    185       double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
     185      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
    186186      TestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
    187187
    188       double trainingNmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
     188      double trainingNmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
    189189      TrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNmse : double.NaN;
    190       double testNmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
     190      double testNmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
    191191      TestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNmse : double.NaN;
    192192
    193       double trainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
     193      var startTrainingValues = originalTrainingValues;
     194      // each continuation is only one element long
     195      var actualContinuationsTraining = from x in originalTrainingValues.Skip(1)
     196                                        select Enumerable.Repeat(x, 1);
     197      // each forecast is only one elemnt long
     198      // disregards the first estimated value (we could include this again by extending the list of original values by one step to the left
     199      // this is the easier way
     200      var predictedContinuationsTraining = from x in estimatedTrainingValues.Skip(1)
     201                                           select Enumerable.Repeat(x, 1);
     202
     203      var startTestValues = originalTestValues;
     204      var actualContinuationsTest = from x in originalTestValues.Skip(1)
     205                                    select Enumerable.Repeat(x, 1);
     206      var predictedContinuationsTest = from x in estimatedTestValues.Skip(1)
     207                                       select Enumerable.Repeat(x, 1);
     208
     209      double trainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(startTrainingValues, actualContinuationsTraining, predictedContinuationsTraining, out errorState);
    194210      TrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? trainingDirectionalSymmetry : double.NaN;
    195       double testDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
     211      double testDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(startTestValues, actualContinuationsTest, predictedContinuationsTest, out errorState);
    196212      TestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? testDirectionalSymmetry : double.NaN;
    197213
    198       double trainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
     214      double trainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(startTrainingValues, actualContinuationsTraining, predictedContinuationsTraining, out errorState);
    199215      TrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? trainingWeightedDirectionalSymmetry : double.NaN;
    200       double testWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
     216      double testWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(startTestValues, actualContinuationsTest, predictedContinuationsTest, out errorState);
    201217      TestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? testWeightedDirectionalSymmetry : double.NaN;
    202218
    203       double trainingTheilsU = OnlineTheilsUStatisticCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
     219      double trainingTheilsU = OnlineTheilsUStatisticCalculator.Calculate(startTrainingValues, actualContinuationsTraining, predictedContinuationsTraining, out errorState);
    204220      TrainingTheilsUStatistic = errorState == OnlineCalculatorError.None ? trainingTheilsU : double.NaN;
    205       double testTheilsU = OnlineTheilsUStatisticCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
     221      double testTheilsU = OnlineTheilsUStatisticCalculator.Calculate(startTestValues, actualContinuationsTest, predictedContinuationsTest, out errorState);
    206222      TestTheilsUStatistic = errorState == OnlineCalculatorError.None ? testTheilsU : double.NaN;
    207 
    208 
    209223    }
    210224  }
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs

    r6802 r7099  
    2222using System;
    2323using System.Collections.Generic;
     24using HeuristicLab.Common;
    2425
    2526
    2627namespace HeuristicLab.Problems.DataAnalysis {
    27   public class OnlineDirectionalSymmetryCalculator : IOnlineCalculator {
    28     private double prevEstimated;
    29     private double prevOriginal;
     28  public class OnlineDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator {
    3029    private int n;
    3130    private int nCorrect;
     
    3332    public double DirectionalSymmetry {
    3433      get {
    35         if (n <= 1) return 0.0;
    36         return (double)nCorrect / (n - 1) * 100.0;
     34        if (n < 1) return 0.0;
     35        return (double)nCorrect / n;
    3736      }
    3837    }
     
    5150    }
    5251
    53     public void Add(double original, double estimated) {
    54       if (double.IsNaN(estimated) || double.IsInfinity(estimated) || double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
     52    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
     53      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
    5554        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
    56       } else if (n == 0) {
    57         prevOriginal = original;
    58         prevEstimated = estimated;
    59         n++;
    6055      } else {
    61         if ((original - prevOriginal) * (estimated - prevEstimated) >= 0.0) {
    62           nCorrect++;
     56        var actualEnumerator = actualContinuation.GetEnumerator();
     57        var predictedEnumerator = predictedContinuation.GetEnumerator();
     58        double prevActual = startValue;
     59        double prevPredicted = startValue;
     60        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & errorState != OnlineCalculatorError.InvalidValueAdded) {
     61          double actual = actualEnumerator.Current;
     62          double predicted = predictedEnumerator.Current;
     63          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
     64            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
     65          } else {
     66            // count a prediction correct if the trend (positive/negative/no change) is predicted correctly
     67            if ((actual - prevActual) * (predicted - prevPredicted) > 0.0 ||
     68                (actual - prevActual).IsAlmost(predicted - prevPredicted)
     69              ) {
     70              nCorrect++;
     71            }
     72            n++;
     73          }
    6374        }
    64         n++;
    65         errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
    66         prevOriginal = original;
    67         prevEstimated = estimated;
     75        // check if both enumerators are at the end to make sure both enumerations have the same length
     76        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
     77          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
     78        } else {
     79          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
     80        }
    6881      }
    6982    }
     
    7285      n = 0;
    7386      nCorrect = 0;
    74       prevOriginal = double.NaN;
    75       prevEstimated = double.NaN;
    7687      errorState = OnlineCalculatorError.InsufficientElementsAdded;
    7788    }
    7889
    7990
    80     public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
    81       IEnumerator<double> firstEnumerator = first.GetEnumerator();
    82       IEnumerator<double> secondEnumerator = second.GetEnumerator();
     91    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
     92      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
     93      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
     94      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
    8395      OnlineDirectionalSymmetryCalculator dsCalculator = new OnlineDirectionalSymmetryCalculator();
    8496
    85       // add first element of time series as a reference point
    86       firstEnumerator.MoveNext();
    87       secondEnumerator.MoveNext();
    88       dsCalculator.Add(firstEnumerator.Current, secondEnumerator.Current);
    89      
    90       // always move forward both enumerators (do not use short-circuit evaluation!)
    91       while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
    92         double estimated = secondEnumerator.Current;
    93         double original = firstEnumerator.Current;
    94         dsCalculator.Add(original, estimated);
     97      // always move forward all enumerators (do not use short-circuit evaluation!)
     98      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
     99        dsCalculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
    95100        if (dsCalculator.ErrorState != OnlineCalculatorError.None) break;
    96101      }
    97102
    98       // check if both enumerators are at the end to make sure both enumerations have the same length
     103      // check if all enumerators are at the end to make sure both enumerations have the same length
    99104      if (dsCalculator.ErrorState == OnlineCalculatorError.None &&
    100           (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
    101         throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
     105          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
     106        throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match.");
    102107      } else {
    103108        errorState = dsCalculator.ErrorState;
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs

    r6802 r7099  
    2222using System;
    2323using System.Collections.Generic;
     24using HeuristicLab.Common;
    2425
    2526namespace HeuristicLab.Problems.DataAnalysis {
    26   public class OnlineTheilsUStatisticCalculator : IOnlineCalculator {
     27  public class OnlineTheilsUStatisticCalculator : IOnlineTimeSeriesCalculator {
    2728    private OnlineMeanAndVarianceCalculator squaredErrorMeanCalculator;
    2829    private OnlineMeanAndVarianceCalculator unbiasedEstimatorMeanCalculator;
    29     private double prevOriginal;
    30     private int n;
    3130
    3231    public double TheilsUStatistic {
     
    5251    }
    5352
    54     public void Add(double original, double estimated) {
    55       if (double.IsNaN(estimated) || double.IsInfinity(estimated) || double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
     53    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
     54      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
    5655        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
    57       } else if (n == 0) {
    58         prevOriginal = original;
    59         n++;
    6056      } else {
    61         // error of predicted change
    62         double errorEstimatedChange = (estimated - original);
    63         squaredErrorMeanCalculator.Add(errorEstimatedChange * errorEstimatedChange);
     57        var actualEnumerator = actualContinuation.GetEnumerator();
     58        var predictedEnumerator = predictedContinuation.GetEnumerator();
     59        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & ErrorState != OnlineCalculatorError.InvalidValueAdded) {
     60          double actual = actualEnumerator.Current;
     61          double predicted = predictedEnumerator.Current;
     62          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
     63            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
     64          } else {
     65            // error of predicted change
     66            double errorPredictedChange = (predicted - startValue) - (actual - startValue);
     67            squaredErrorMeanCalculator.Add(errorPredictedChange * errorPredictedChange);
    6468
    65         double errorNoChange = (original - prevOriginal);
    66         unbiasedEstimatorMeanCalculator.Add(errorNoChange * errorNoChange);
    67         errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
     69            double errorNoChange = (actual - startValue);
     70            unbiasedEstimatorMeanCalculator.Add(errorNoChange * errorNoChange);
     71          }
     72        }
     73        // check if both enumerators are at the end to make sure both enumerations have the same length
     74        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
     75          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
     76        } else {
     77          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
     78        }
    6879      }
    6980    }
    7081
    71 
    7282    public void Reset() {
    73       prevOriginal = double.NaN;
    74       n = 0;
    7583      squaredErrorMeanCalculator.Reset();
    7684      unbiasedEstimatorMeanCalculator.Reset();
     
    8088    #endregion
    8189
    82     public static double Calculate(IEnumerable<double> estimatedValues, IEnumerable<double> originalValues, out OnlineCalculatorError errorState) {
    83       IEnumerator<double> originalValuesEnumerator = originalValues.GetEnumerator();
    84       IEnumerator<double> estimatedValuesEnumerator = estimatedValues.GetEnumerator();
     90    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
     91      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
     92      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
     93      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
    8594      OnlineTheilsUStatisticCalculator calculator = new OnlineTheilsUStatisticCalculator();
    8695
    87       // add first element of time series as a reference point
    88       originalValuesEnumerator.MoveNext();
    89       estimatedValuesEnumerator.MoveNext();
    90       calculator.Add(originalValuesEnumerator.Current, estimatedValuesEnumerator.Current);
    91 
    92       // always move forward both enumerators (do not use short-circuit evaluation!)
    93       while (originalValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) {
    94         double estimated = estimatedValuesEnumerator.Current;
    95         double original = originalValuesEnumerator.Current;
    96         calculator.Add(original, estimated);
     96      // always move forward all enumerators (do not use short-circuit evaluation!)
     97      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
     98        calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
    9799        if (calculator.ErrorState != OnlineCalculatorError.None) break;
    98100      }
    99101
    100       // check if both enumerators are at the end to make sure both enumerations have the same length
     102      // check if all enumerators are at the end to make sure both enumerations have the same length
    101103      if (calculator.ErrorState == OnlineCalculatorError.None &&
    102           (estimatedValuesEnumerator.MoveNext() || originalValuesEnumerator.MoveNext())) {
    103         throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
     104          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
     105        throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match.");
    104106      } else {
    105107        errorState = calculator.ErrorState;
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs

    r6802 r7099  
    2222using System;
    2323using System.Collections.Generic;
     24using HeuristicLab.Common;
    2425
    2526
    2627namespace HeuristicLab.Problems.DataAnalysis {
    27   public class OnlineWeightedDirectionalSymmetryCalculator : IOnlineCalculator {
     28  public class OnlineWeightedDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator {
    2829    private double prevEstimated;
    2930    private double prevOriginal;
     
    5253    }
    5354
    54     public void Add(double original, double estimated) {
    55       if (double.IsNaN(estimated) || double.IsInfinity(estimated) || double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
     55    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
     56      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
    5657        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
    57       } else if (n == 0) {
    58         prevOriginal = original;
    59         prevEstimated = estimated;
    60         n++;
    6158      } else {
    62         double err = Math.Abs(original - estimated);
    63         if ((original - prevOriginal) * (estimated - prevEstimated) >= 0.0) {
    64           correctSum += err;
     59        var actualEnumerator = actualContinuation.GetEnumerator();
     60        var predictedEnumerator = predictedContinuation.GetEnumerator();
     61        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & errorState != OnlineCalculatorError.InvalidValueAdded) {
     62          double actual = actualEnumerator.Current;
     63          double predicted = predictedEnumerator.Current;
     64          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
     65            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
     66          } else {
     67            double err = Math.Abs(actual - predicted);
     68            // count as correct only if the trend (positive/negative/no change) is predicted correctly
     69            if ((actual - startValue) * (predicted - startValue) > 0.0 ||
     70              (actual - startValue).IsAlmost(predicted - startValue)) {
     71              correctSum += err;
     72            } else {
     73              incorrectSum += err;
     74            }
     75            n++;
     76          }
     77        }
     78        // check if both enumerators are at the end to make sure both enumerations have the same length
     79        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
     80          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
    6581        } else {
    66           incorrectSum += err;
     82          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
    6783        }
    68         n++;
    69         errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
    70         prevOriginal = original;
    71         prevEstimated = estimated;
    7284      }
    7385    }
     
    8395
    8496
    85     public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
    86       IEnumerator<double> firstEnumerator = first.GetEnumerator();
    87       IEnumerator<double> secondEnumerator = second.GetEnumerator();
    88       OnlineDirectionalSymmetryCalculator dsCalculator = new OnlineDirectionalSymmetryCalculator();
    89      
    90       // add first element of time series as a reference point
    91       firstEnumerator.MoveNext();
    92       secondEnumerator.MoveNext();
    93       dsCalculator.Add(firstEnumerator.Current, secondEnumerator.Current);
     97    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
     98      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
     99      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
     100      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
     101      OnlineWeightedDirectionalSymmetryCalculator calculator = new OnlineWeightedDirectionalSymmetryCalculator();
    94102
    95       // always move forward both enumerators (do not use short-circuit evaluation!)
    96       while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
    97         double estimated = secondEnumerator.Current;
    98         double original = firstEnumerator.Current;
    99         dsCalculator.Add(original, estimated);
    100         if (dsCalculator.ErrorState != OnlineCalculatorError.None) break;
     103      // always move forward all enumerators (do not use short-circuit evaluation!)
     104      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
     105        calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
     106        if (calculator.ErrorState != OnlineCalculatorError.None) break;
    101107      }
    102108
    103       // check if both enumerators are at the end to make sure both enumerations have the same length
    104       if (dsCalculator.ErrorState == OnlineCalculatorError.None &&
    105           (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
    106         throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
     109      // check if all enumerators are at the end to make sure both enumerations have the same length
     110      if (calculator.ErrorState == OnlineCalculatorError.None &&
     111          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
     112        throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match.");
    107113      } else {
    108         errorState = dsCalculator.ErrorState;
    109         return dsCalculator.DirectionalSymmetry;
     114        errorState = calculator.ErrorState;
     115        return calculator.WeightedDirectionalSymmetry;
    110116      }
    111117    }
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis-3.4/StatisticCalculatorsTest.cs

    r7097 r7099  
    2020#endregion
    2121
     22using System;
    2223using System.Collections.Generic;
    2324using System.Linq;
     
    139140      }
    140141    }
     142
     143    [TestMethod]
     144    public void CalculateDirectionalSymmetryTest() {
     145      // delta: +0.01, +1, -0.01, -2, -0.01, -1, +0.01, +2
     146      var original = new double[]
     147                       {
     148                         0,
     149                         0.01,
     150                         1.01,
     151                         1,
     152                         -1,
     153                         -1.01,
     154                         -2.01,
     155                         -2,
     156                         0
     157                       };
     158      // delta to original(t-1): +1, +0, -1, -0, -1, +0.01, +0.01, +2
     159      var estimated = new double[]
     160                        {
     161                          -1,
     162                          1,
     163                          0.01,
     164                          0.01,
     165                          1,
     166                          -1,
     167                          -1.02,
     168                          -2.02,
     169                          0
     170                        };
     171
     172      // one-step forecast
     173      var startValues = original;
     174      var actualContinuations = from x in original.Skip(1)
     175                                select Enumerable.Repeat(x, 1);
     176      var predictedContinuations = from x in estimated.Skip(1)
     177                                   select Enumerable.Repeat(x, 1);
     178      double expected = 0.5;  // half of the predicted deltas are correct
     179      OnlineCalculatorError errorState;
     180      double actual = OnlineDirectionalSymmetryCalculator.Calculate(startValues, actualContinuations, predictedContinuations, out errorState);
     181      Assert.AreEqual(expected, actual, 1E-9);
     182    }
     183
     184    [TestMethod]
     185    public void CalculateMultiStepDirectionalSymmetryTest() {
     186      // delta: +0.01, +1, -0.01, -2, -0.01, -1, +0.01, +2
     187      var original = new double[] { 0, 0.01, 1.01, 1, -1, -1.01, -2.01, -2, 0 };
     188      {
     189        var estimated = new double[][]
     190                          {
     191                            new double[] {0.01, 1.01, 1, -1, -1.01},
     192                            new double[] {1.01, 1, -1, -1.01, -2.01},
     193                            new double[] {1, -1, -1.01, -2.01, -2},
     194                            new double[] {-1, -1.01, -2.01, -2, 0}
     195                          };
     196
     197        // 5-step forecast
     198        var startValues = original.Take(4);
     199        var actualContinuations = from i in Enumerable.Range(1, original.Count() - 5)
     200                                  select original.Skip(i).Take(5);
     201        var predictedContinuations = estimated;
     202        double expected = 1; // predictions are 100% correct
     203        OnlineCalculatorError errorState;
     204        double actual = OnlineDirectionalSymmetryCalculator.Calculate(startValues, actualContinuations,
     205                                                                      predictedContinuations, out errorState);
     206        Assert.AreEqual(expected, actual, 1E-9);
     207      }
     208      {
     209        // only the direction is relevant
     210        var estimated = new double[][]
     211                          {
     212                            new double[] {0.01, 0.01, 0.01, -0.01, -0.01},  // start=0, original deltas: 0.01, 1.01, 1.00, -1.00, -1.01
     213                            new double[] {0.02, 0.02, 0.00, 0.00, 0.00}, // start=0.01, original deltas: 1.00, 0.90, -1.01, -1.02, -2.02,
     214                            new double[] { 1.00, 1.00, 1.00, 1.00, 1.00}, // start=1.01, original deltas: -0.01, -2.01, -2.02, -3.02, -3.01
     215                            new double[] { 0.90, 0.90, 0.90, 0.90, 0.90}  // start=1, original deltas: -2.00, -0.01, -3.01, -3.00, -1.00
     216                          };
     217
     218        // 5-step forecast
     219        var startValues = original.Take(4);
     220        var actualContinuations = from i in Enumerable.Range(1, original.Count() - 5)
     221                                  select original.Skip(i).Take(5);
     222        var predictedContinuations = estimated;
     223        double expected = 1; // half of the predicted deltas are correct
     224        OnlineCalculatorError errorState;
     225        double actual = OnlineDirectionalSymmetryCalculator.Calculate(startValues, actualContinuations,
     226                                                                      predictedContinuations, out errorState);
     227        Assert.AreEqual(expected, actual, 1E-9);
     228      }
     229      {
     230        // also check incorrectly predicted directions
     231        var estimated = new double[][]
     232                          {
     233                            new double[] {0.01, 0.01, 0.01, +0.01, +0.01},  // start=0, original deltas: 0.01, 1.01, 1.00, -1.00, -1.01
     234                            new double[] {0.02, 0.00, 0.02, 0.00, 0.00}, // start=0.01, original deltas: 1.00, 0.90, -1.01, -1.02, -2.02,
     235                            new double[] { 1.02, 1.00, 1.02, 1.00, 1.02}, // start=1.01, original deltas: -0.01, -2.01, -2.02, -3.02, -3.01
     236                            new double[] { 0.90, 0.90, 0.90, 0.90, 0.90}  // start=1, original deltas: -2.00, -0.01, -3.01, -3.00, -1.00
     237                          };
     238
     239        // 5-step forecast
     240        var startValues = original.Take(4);
     241        var actualContinuations = from i in Enumerable.Range(1, original.Count() - 5)
     242                                  select original.Skip(i).Take(5);
     243        var predictedContinuations = estimated;
     244        double expected = (20 - 7) / 20.0; // half of the predicted deltas are correct
     245        OnlineCalculatorError errorState;
     246        double actual = OnlineDirectionalSymmetryCalculator.Calculate(startValues, actualContinuations,
     247                                                                      predictedContinuations, out errorState);
     248        Assert.AreEqual(expected, actual, 1E-9);
     249      }
     250    }
     251
     252
     253    [TestMethod]
     254    public void CalculateWeightedDirectionalSymmetryTest() {
     255      var original = new double[] { 0, 0.01, 1.01, 1, -1, -1.01, -2.01, -2, 0 }; // +0.01, +1, -0.01, -2, -0.01, -1, +0.01, +2
     256      var estimated = new double[] { 1, 2, 2, 1, 1, 0, 0.01, 0.02, 2.02 }; // delta to original: +2, +1.99, -0.01, 0, +1, -1.02, +2.01, +4.02
     257      // one-step forecast
     258      var startValues = original;
     259      var actualContinuations = from x in original.Skip(1)
     260                                select Enumerable.Repeat(x, 1);
     261      var predictedContinuations = from x in estimated.Skip(1)
     262                                   select Enumerable.Repeat(x, 1);
     263      // absolute errors = 1.99, 0.99, 0, 2, 1.01, 2.02, 2.02, 2.02     
     264      // sum of absolute errors for correctly predicted deltas = 2.97
     265      // sum of absolute errors for incorrectly predicted deltas = 3.03
     266      double expected = 5.03 / 7.02;
     267      OnlineCalculatorError errorState;
     268      double actual = OnlineWeightedDirectionalSymmetryCalculator.Calculate(startValues, actualContinuations, predictedContinuations, out errorState);
     269      Assert.AreEqual(expected, actual, 1E-9);
     270    }
     271
     272    [TestMethod]
     273    public void CalculateTheilsUTest() {
     274      var original = new double[] { 0, 0.01, 1.01, 1, -1, -1.01, -2.01, -2, 0 };
     275      var estimated = new double[] { 1, 1.01, 0.01, 2, 0, -0.01, -1.01, -3, 1 };
     276      // one-step forecast
     277      var startValues = original;
     278      var actualContinuations = from x in original.Skip(1)
     279                                select Enumerable.Repeat(x, 1);
     280      var predictedContinuations = from x in estimated.Skip(1)
     281                                   select Enumerable.Repeat(x, 1);
     282      // Sum of squared errors of model y(t+1) = y(t) = 10.0004
     283      // Sum of squared errors of predicted values = 8 
     284      double expected = Math.Sqrt(8 / 10.0004);
     285      OnlineCalculatorError errorState;
     286      double actual = OnlineTheilsUStatisticCalculator.Calculate(startValues, actualContinuations, predictedContinuations, out errorState);
     287      Assert.AreEqual(expected, actual, 1E-9);
     288    }
     289
     290    [TestMethod]
     291    public void CalculateMultiStepTheilsUTest() {
     292      var original = new double[] { 0, 0.01, 1.01, 1, -1, -1.01, -2.01, -2, 0 };
     293      {
     294        // prefect prediction
     295        var estimated = new double[][]
     296                          {
     297                            new double[] {0.01, 1.01, 1, -1, -1.01},
     298                            new double[] {1.01, 1, -1, -1.01, -2.01},
     299                            new double[] {1, -1, -1.01, -2.01, -2},
     300                            new double[] {-1, -1.01, -2.01, -2, 0}
     301                          };
     302        // 5-step forecast
     303        var startValues = original.Take(4);
     304        var actualContinuations = from i in Enumerable.Range(1, original.Count() - 5)
     305                                  select original.Skip(i).Take(5);
     306        var predictedContinuations = estimated;
     307
     308        double expected = 0;
     309        OnlineCalculatorError errorState;
     310        double actual = OnlineTheilsUStatisticCalculator.Calculate(startValues, actualContinuations,
     311                                                                   predictedContinuations, out errorState);
     312        Assert.AreEqual(expected, actual, 1E-9);
     313      }
     314      {
     315        // naive prediction
     316        var estimated = new double[][]
     317                          {
     318                            new double[] {0, 0, 0, 0, 0},
     319                            new double[] {0.01, 0.01, 0.01, 0.01, 0.01},
     320                            new double[] {1.01, 1.01, 1.01, 1.01, 1.01},
     321                            new double[] {1, 1, 1, 1, 1}
     322                          };
     323        // 5-step forecast
     324        var startValues = original.Take(4);
     325        var actualContinuations = from i in Enumerable.Range(1, original.Count() - 5)
     326                                  select original.Skip(i).Take(5);
     327        var predictedContinuations = estimated;
     328
     329        double expected = 1;
     330        OnlineCalculatorError errorState;
     331        double actual = OnlineTheilsUStatisticCalculator.Calculate(startValues, actualContinuations,
     332                                                                   predictedContinuations, out errorState);
     333        Assert.AreEqual(expected, actual, 1E-9);
     334      }
     335      {
     336        // realistic prediction
     337        var estimated = new double[][]
     338                          {
     339                            new double[] {0.005, 0.5, 0.5, -0.5, -0.5},    // start = 0
     340                            new double[] {0.60, 0.5, -0.5, -0.5, -1},   // start = 0.01
     341                            new double[] {-0.005, 0, 0, -0.5, -1},     // start = 1.01
     342                            new double[] {-0, 0, -0.5, -1, 0.5}      // start = 1
     343                          };
     344        // 5-step forecast
     345        var startValues = original.Take(4);
     346        var actualContinuations = from i in Enumerable.Range(1, original.Count() - 5)
     347                                  select original.Skip(i).Take(5);
     348        var predictedContinuations = estimated;
     349
     350        double expected = 0.47558387;
     351        OnlineCalculatorError errorState;
     352        double actual = OnlineTheilsUStatisticCalculator.Calculate(startValues, actualContinuations,
     353                                                                   predictedContinuations, out errorState);
     354        Assert.AreEqual(expected, actual, 1E-6);
     355      }
     356    }
     357
     358    [TestMethod]
     359    public void CalculateAccuracyTest() {
     360      var original = new double[] { 1, 1, 0, 0 };
     361      var estimated = new double[] { 1, 0, 1, 0 };
     362      double expected = 0.5;
     363      OnlineCalculatorError errorState;
     364      double actual = OnlineAccuracyCalculator.Calculate(original, estimated, out errorState);
     365      Assert.AreEqual(expected, actual, 1E-9);
     366    }
     367
     368    [TestMethod]
     369    public void CalculateMeanAbsolutePercentageErrorTest() {
     370      var original = new double[] { 1, 2, 3, 1, 5 };
     371      var estimated = new double[] { 2, 1, 3, 1, 0 };
     372      double expected = 0.5;
     373      OnlineCalculatorError errorState;
     374      double actual = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(original, estimated, out errorState);
     375      Assert.AreEqual(expected, actual, 1E-9);
     376      Assert.AreEqual(OnlineCalculatorError.None, errorState);
     377
     378      // if the original contains zero values the result is not defined
     379      var original2 = new double[] { 1, 2, 0, 0, 0 };
     380      OnlineMeanAbsolutePercentageErrorCalculator.Calculate(original2, estimated, out errorState);
     381      Assert.AreEqual(OnlineCalculatorError.InvalidValueAdded, errorState);
     382    }
    141383  }
    142384}
Note: See TracChangeset for help on using the changeset viewer.