public IForecastingDataSets Select(IPredicationSchema schema)
        {
            int startYear  = schema.Start.Year;
            int startMonth = schema.Start.Month;
            int startDay   = schema.Start.Day;
            int endYear    = schema.End.Year;
            int endMonth   = schema.End.Month;
            int endDay     = schema.End.Day;

            IForecastingDataSets[] sets = new IForecastingDataSets[endYear - startYear + 1];
            for (int i = startYear; i <= endYear; i++)
            {
                DateTime          start        = new DateTime(i, startMonth, startDay);
                DateTime          end          = new DateTime(i, endMonth, endDay);
                PredicationSchema clonedSchema = new PredicationSchema(schema.Stimulus, schema.Responses)
                {
                    Start      = start,
                    End        = end,
                    TimePeriod = schema.TimePeriod
                };
                RollingSelection rollSlct = new RollingSelection();
                sets[i - startYear] = rollSlct.Select(clonedSchema);
            }
            ForecastingDataSets result = ForecastingDataSets.Merge(sets);

            schema.InstancesCount = result.InputData.Length;
            return(result);
        }
        public static ForecastingDataSets Merge(IForecastingDataSets[] sets)
        {
            ForecastingDataSets result = null;

            if (sets != null)
            {
                int        length          = (from s in sets select s.InputData.Length).Sum();
                int        dimension       = sets[0].InputData[0].Length;
                int        outputDimension = sets[0].OutputData[0].Length;
                int        i       = 0;
                double[][] inputs  = new double[length][];
                double[][] outputs = new double[length][];
                DateTime[] date    = new DateTime[length];
                foreach (IForecastingDataSets set in sets)
                {
                    for (int j = 0; j < set.InputData.Length; j++)
                    {
                        inputs[i]  = new double[dimension];
                        outputs[i] = new double[outputDimension];
                        for (int c = 0; c < dimension; c++)
                        {
                            inputs[i][c] = set.InputData[j][c];
                        }
                        for (int c = 0; c < outputDimension; c++)
                        {
                            outputs[i][c] = set.OutputData[j][c];
                        }
                        date[i] = set.Date[j];
                        i++;
                    }
                }

                result = new ForecastingDataSets(inputs, outputs)
                {
                    Date = date
                };
            }
            return(result);
        }
        public IForecastingDataSets Select(IPredicationSchema schema)
        {
            DataCube <double>[] tsList  = new DataCube <double> [schema.Stimulus.Length];
            int [] startIndexOfStimulus = new int[schema.Stimulus.Length];
            int    i           = 0;
            int    valuesCount = 0;

            DateTime[] dates = null;
            foreach (IVariable v in schema.Stimulus)
            {
                TimeSeriesQueryCriteria qc = new TimeSeriesQueryCriteria()
                {
                    Start      = schema.Start,
                    End        = schema.End,
                    SiteID     = v.SiteID,
                    VariableID = v.VariableID
                };
                tsList[i] = v.GetValues(qc, mOdmAdaptor);
                if (v.NormalizationModel != null)
                {
                    v.NormalizationModel.Normalize(tsList[i][0, ":", "0"]);
                }
                if (i == 0)
                {
                    valuesCount = tsList[i].Size[1];
                }
                else
                {
                    if (valuesCount != tsList[i].Size[1])
                    {
                        throw new Exception("The value counts of the  input variables are not identical!");
                    }
                }
                startIndexOfStimulus[i] = schema.MaximumWindowSize - v.WindowSize;
                i++;
            }
            schema.InstancesCount = valuesCount - schema.MaximumWindowSize - schema.PredicationSize;

            dates = new DateTime[schema.InstancesCount];

            ForecastingSetsBuilder builder = new ForecastingSetsBuilder(schema);

            double [][] inputData = builder.BuildInputSets(startIndexOfStimulus, tsList);

            i      = 0;
            tsList = new DataCube <double> [schema.Responses.Length];
            int [] startIndexOfResponses = new int[schema.Responses.Length];
            foreach (IVariable v in schema.Responses)
            {
                TimeSeriesQueryCriteria qc = new TimeSeriesQueryCriteria()
                {
                    Start      = schema.Start,
                    End        = schema.End,
                    SiteID     = v.SiteID,
                    VariableID = v.VariableID
                };
                tsList[i] = v.GetValues(qc, mOdmAdaptor);
                if (v.NormalizationModel != null)
                {
                    v.NormalizationModel.Normalize(tsList[i][0, ":", "0"]);
                }
                if (valuesCount != tsList[i].Size[1])
                {
                    throw new Exception("The value counts of the  input variables are not identical!");
                }
                startIndexOfResponses[i] = schema.MaximumWindowSize + v.PredicationSize;
                if (i == 0)
                {
                    System.Array.Copy(tsList[i].DateTimes, startIndexOfResponses[i], dates, 0, schema.InstancesCount);
                }
                i++;
            }
            double[][] outputData = builder.BuildOutputSets(startIndexOfResponses, tsList);

            ForecastingDataSets result = new ForecastingDataSets(inputData, outputData)
            {
                Date = dates
            };

            return(result);
        }