private static DocumentCollection GetDocumentCollection(
            string collectionId,
            string partitionKey       = null,
            IndexingMode indexingMode = IndexingMode.Consistent)
        {
            var documentCollection = new DocumentCollection();

            documentCollection.Id = collectionId;

            var rangeIndex = new RangeIndex(DataType.String);

            rangeIndex.Precision = -1;
            var indexingPolicy = new IndexingPolicy(rangeIndex);

            indexingPolicy.IndexingMode       = indexingMode;
            documentCollection.IndexingPolicy = indexingPolicy;

            if (partitionKey != null)
            {
                var partitionKeyDefinition = new PartitionKeyDefinition();
                partitionKeyDefinition.Paths = new Collection <string> {
                    partitionKey
                };
                documentCollection.PartitionKey = partitionKeyDefinition;
            }

            return(documentCollection);
        }
 private static DocumentCollection CreateCollection()
 {
     return(BinaryEncodingOverTheWireTests.Client.CreateDocumentCollectionAsync(
                UriFactory.CreateDatabaseUri(BinaryEncodingOverTheWireTests.database.Id),
                new DocumentCollection
     {
         Id = Guid.NewGuid().ToString() + "collection",
         IndexingPolicy = new IndexingPolicy
         {
             IncludedPaths = new Collection <IncludedPath>
             {
                 new IncludedPath
                 {
                     Path = "/*",
                     Indexes = new Collection <Index>
                     {
                         RangeIndex.Range(DataType.Number, -1),
                         RangeIndex.Range(DataType.String, -1),
                     }
                 }
             }
         },
     },
                new RequestOptions {
         OfferThroughput = 10000
     }).Result);
 }
        public async Task <ResourceResponse <DocumentCollection> > CreateCollectionIfNotExistsAsync(
            string databaseName,
            string id)
        {
            DocumentCollection collectionInfo = new DocumentCollection();
            RangeIndex         index          = Index.Range(DataType.String, -1);

            collectionInfo.IndexingPolicy = new IndexingPolicy(
                new Index[] { index });
            collectionInfo.Id = id;

            // Azure Cosmos DB collections can be reserved with
            // throughput specified in request units/second.
            RequestOptions requestOptions = new RequestOptions();

            requestOptions.OfferThroughput = this.storageThroughput;
            string dbUrl  = "/dbs/" + databaseName;
            string colUrl = dbUrl + "/colls/" + id;
            bool   create = false;
            ResourceResponse <DocumentCollection> response = null;

            try
            {
                response = await this.client.ReadDocumentCollectionAsync(
                    colUrl,
                    requestOptions);
            }
            catch (DocumentClientException dcx)
            {
                if (dcx.StatusCode == HttpStatusCode.NotFound)
                {
                    create = true;
                }
                else
                {
                    this.log.Error("Error reading collection.",
                                   () => new { id, dcx });
                }
            }

            if (create)
            {
                try
                {
                    response = await this.client.CreateDocumentCollectionAsync(
                        dbUrl,
                        collectionInfo,
                        requestOptions);
                }
                catch (Exception ex)
                {
                    this.log.Error("Error creating collection.",
                                   () => new { id, dbUrl, collectionInfo, ex });
                    throw;
                }
            }

            return(response);
        }
        public void WipeUnitTest()
        {
            Assert.Inconclusive("TODO");

            var target = new RangeIndex(); // TODO: Initialize to an appropriate value

            target.Wipe();
        }
Example #5
0
        public void MergeCells(RangeIndex initial, RangeIndex final, string text = null)
        {
            worksheet.Range[worksheet.Cells[initial.Initial, initial.Final], worksheet.Cells[final.Initial, final.Final]].Merge();

            if (!string.IsNullOrEmpty(text))
            {
                worksheet.Cells[initial.Initial, initial.Final] = text;
            }
        }
        public void RemoveValueUnitTest()
        {
            Assert.Inconclusive("TODO");

            var           target       = new RangeIndex(); // TODO: Initialize to an appropriate value
            AGraphElement graphElement = null;             // TODO: Initialize to an appropriate value

            target.RemoveValue(graphElement);
        }
        public async Task <ResourceResponse <DocumentCollection> > CreateCollectionIfNotExistsAsync(
            string databaseName,
            string id,
            string partitionKeyName = null)
        {
            RangeIndex         index          = Index.Range(DataType.String, -1);
            DocumentCollection collectionInfo = new DocumentCollection
            {
                IndexingPolicy = new IndexingPolicy(new Index[] { index }),
                Id             = id,
            };

            if (!string.IsNullOrEmpty(partitionKeyName))
            {
                collectionInfo.PartitionKey = new PartitionKeyDefinition
                {
                    Paths = new Collection <string> {
                        $"/{partitionKeyName}"
                    },
                };
            }

            // Azure Cosmos DB collections can be reserved with
            // throughput specified in request units/second.
            RequestOptions requestOptions = new RequestOptions
            {
                OfferThroughput  = this.storageThroughput,
                ConsistencyLevel = ConsistencyLevel.Strong,
            };
            string dbUrl = "/dbs/" + databaseName;

            try
            {
                await this.CreateDatabaseIfNotExistsAsync(databaseName);
            }
            catch (Exception e)
            {
                throw new Exception($"While attempting to create collection {id}, an error occured while attepmting to create its database {databaseName}.", e);
            }

            ResourceResponse <DocumentCollection> response;

            try
            {
                response = await this.client.CreateDocumentCollectionIfNotExistsAsync(
                    dbUrl,
                    collectionInfo,
                    requestOptions);
            }
            catch (Exception e)
            {
                this.logger.LogError(e, "Error creating collection with ID {id}, database URL {databaseUrl}, and collection info {collectionInfo}", id, dbUrl, collectionInfo);
                throw;
            }

            return(response);
        }
        public void AddOrUpdateUnitTest()
        {
            Assert.Inconclusive("TODO");

            var           target       = new RangeIndex(); // TODO: Initialize to an appropriate value
            object        keyObject    = null;             // TODO: Initialize to an appropriate value
            AGraphElement graphElement = null;             // TODO: Initialize to an appropriate value

            target.AddOrUpdate(keyObject, graphElement);
        }
        public void CountOfValuesUnitTest()
        {
            Assert.Inconclusive("TODO");

            var target   = new RangeIndex(); // TODO: Initialize to an appropriate value
            int expected = 0;                // TODO: Initialize to an appropriate value
            int actual;

            actual = target.CountOfValues();
            Assert.AreEqual(expected, actual);
        }
        public void GetKeyValuesUnitTest()
        {
            Assert.Inconclusive("TODO");

            var target = new RangeIndex();                                                             // TODO: Initialize to an appropriate value
            IEnumerable <KeyValuePair <object, ReadOnlyCollection <AGraphElement> > > expected = null; // TODO: Initialize to an appropriate value
            IEnumerable <KeyValuePair <object, ReadOnlyCollection <AGraphElement> > > actual;

            actual = target.GetKeyValues();
            Assert.AreEqual(expected, actual);
        }
        public void GetKeysUnitTest()
        {
            Assert.Inconclusive("TODO");

            var target = new RangeIndex();        // TODO: Initialize to an appropriate value
            IEnumerable <object> expected = null; // TODO: Initialize to an appropriate value
            IEnumerable <object> actual;

            actual = target.GetKeys();
            Assert.AreEqual(expected, actual);
        }
        public void TryRemoveKeyUnitTest()
        {
            Assert.Inconclusive("TODO");

            var    target    = new RangeIndex(); // TODO: Initialize to an appropriate value
            object keyObject = null;             // TODO: Initialize to an appropriate value
            bool   expected  = false;            // TODO: Initialize to an appropriate value
            bool   actual;

            actual = target.TryRemoveKey(keyObject);
            Assert.AreEqual(expected, actual);
        }
        public void TryGetValueUnitTest()
        {
            Assert.Inconclusive("TODO");

            var target = new RangeIndex();                            // TODO: Initialize to an appropriate value
            ReadOnlyCollection <AGraphElement> result         = null; // TODO: Initialize to an appropriate value
            ReadOnlyCollection <AGraphElement> resultExpected = null; // TODO: Initialize to an appropriate value
            object keyObject = null;                                  // TODO: Initialize to an appropriate value
            bool   expected  = false;                                 // TODO: Initialize to an appropriate value
            bool   actual;

            actual = target.TryGetValue(out result, keyObject);
            Assert.AreEqual(resultExpected, result);
            Assert.AreEqual(expected, actual);
        }
        public void LowerThanUnitTest()
        {
            Assert.Inconclusive("TODO");

            var target = new RangeIndex();                            // TODO: Initialize to an appropriate value
            ReadOnlyCollection <AGraphElement> result         = null; // TODO: Initialize to an appropriate value
            ReadOnlyCollection <AGraphElement> resultExpected = null; // TODO: Initialize to an appropriate value
            IComparable key        = null;                            // TODO: Initialize to an appropriate value
            bool        includeKey = false;                           // TODO: Initialize to an appropriate value
            bool        expected   = false;                           // TODO: Initialize to an appropriate value
            bool        actual;

            actual = target.LowerThan(out result, key, includeKey);
            Assert.AreEqual(resultExpected, result);
            Assert.AreEqual(expected, actual);
        }
        public void BetweenUnitTest()
        {
            Assert.Inconclusive("TODO");

            var target = new RangeIndex();                            // TODO: Initialize to an appropriate value
            ReadOnlyCollection <AGraphElement> result         = null; // TODO: Initialize to an appropriate value
            ReadOnlyCollection <AGraphElement> resultExpected = null; // TODO: Initialize to an appropriate value
            IComparable lowerLimit        = null;                     // TODO: Initialize to an appropriate value
            IComparable upperLimit        = null;                     // TODO: Initialize to an appropriate value
            bool        includeLowerLimit = false;                    // TODO: Initialize to an appropriate value
            bool        includeUpperLimit = false;                    // TODO: Initialize to an appropriate value
            bool        expected          = false;                    // TODO: Initialize to an appropriate value
            bool        actual;

            actual = target.Between(out result, lowerLimit, upperLimit, includeLowerLimit, includeUpperLimit);
            Assert.AreEqual(resultExpected, result);
            Assert.AreEqual(expected, actual);
        }
Example #16
0
 /// <summary>
 /// Gets maximum value of the provided field.
 /// </summary>
 /// <typeparam name="TField"></typeparam>
 /// <param name="field"></param>
 /// <returns></returns>
 public TField Maximum <TField>(IField <TRecord, TField> field)
 {
     this.table.ValidateField(field);
     if (!this.IsEmpty())
     {
         List <IIndex <TRecord> > list = this.table.Indexes[field.Order];
         if (list != null)
         {
             foreach (IIndex <TRecord> index in list)
             {
                 if (((IFieldHolder)index).Field == field)
                 {
                     RangeIndex <TField> rangeIndex = index as RangeIndex <TField>;
                     if (rangeIndex != null)
                     {
                         return(rangeIndex.MaximumValue(this.StoreSnapshot.Version));
                     }
                 }
             }
         }
         TField max   = field.DefaultValue;
         bool   first = true;
         foreach (RowId rowId in this)
         {
             if (first)
             {
                 max   = this.GetField(rowId, field);
                 first = false;
             }
             else
             {
                 TField value = this.GetField(rowId, field);
                 if (field.Compare(max, value) < 0)
                 {
                     max = value;
                 }
             }
         }
         return(max);
     }
     return(field.DefaultValue);
 }
Example #17
0
        /// <summary>
        /// Selects rows where value of provided field in range from min to max inclusively
        /// </summary>
        /// <typeparam name="TField"></typeparam>
        /// <param name="field"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        public IEnumerable <RowId> Select <TField>(IField <TRecord, TField> field, TField min, TField max)
        {
            this.table.ValidateField(field);
            List <IIndex <TRecord> > list = this.table.Indexes[field.Order];

            if (list != null)
            {
                foreach (IIndex <TRecord> index in list)
                {
                    if (!index.IsUnique)
                    {
                        RangeIndex <TField> rangeIndex = index as RangeIndex <TField>;
                        if (rangeIndex != null && rangeIndex.Field == field)
                        {
                            return(rangeIndex.Find(min, max, this.StoreSnapshot.Version));
                        }
                    }
                }
            }
            return(this.SelectDirect(field, min, max));
        }
Example #18
0
        /// <summary>
        /// Creates the audit collection if it does not already exist.
        /// </summary>
        /// <returns></returns>
        private async Task CreateAuditCollectionIfNotExist()
        {
            using (var client = new DocumentClient(new Uri(this.accountEndpoint), this.accountKey))
            {
                var database = new Database()
                {
                    Id = DatabaseId
                };

                await client.CreateDatabaseIfNotExistsAsync(database);

                var docDefinition = new DocumentCollection();

                var rangeIndex = new RangeIndex(DataType.String)
                {
                    Precision = -1
                };

                docDefinition.Id = CollectionId;

                docDefinition.PartitionKey.Paths.Add("/PartitionKey");

                docDefinition.IndexingPolicy = new IndexingPolicy(rangeIndex);

                docDefinition.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath {
                    Path = "/Data/*"
                });

                var options = new RequestOptions()
                {
                    OfferThroughput = DefaultThroughput
                };

                var cosmosDbUri = UriFactory.CreateDatabaseUri(DatabaseId);

                await client.CreateDocumentCollectionIfNotExistsAsync(cosmosDbUri, docDefinition, options);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TField1"></typeparam>
        /// <typeparam name="TField2"></typeparam>
        /// <param name="name"></param>
        /// <param name="field1"></param>
        /// <param name="field2"></param>
        /// <param name="unique"></param>
        private void CreateIndex <TField1, TField2>(string name, IField <TRecord, TField1> field1, IField <TRecord, TField2> field2, bool unique)
        {
            this.table.ValidateField(field1);
            this.table.ValidateField(field2);
            if (field1 == field2)
            {
                throw new ArgumentException(Properties.Resources.ErrorCompositeFields);
            }
            CompositeField <TField1, TField2>           field = new CompositeField <TField1, TField2>(field1, field2);
            IFieldIndex <Composite <TField1, TField2> > index;

            if (unique)
            {
                index = new UniqueIndex <Composite <TField1, TField2> >(this.table, name, field);
            }
            else
            {
                index = new RangeIndex <Composite <TField1, TField2> >(this.table, name, field);
            }
            List <IIndex <TRecord> > list1 = this.table.Indexes[field1.Order];

            if (list1 == null)
            {
                list1 = new List <IIndex <TRecord> >();
                this.table.Indexes[field1.Order] = list1;
            }
            List <IIndex <TRecord> > list2 = this.table.Indexes[field2.Order];

            if (list2 == null)
            {
                list2 = new List <IIndex <TRecord> >();
                this.table.Indexes[field2.Order] = list2;
            }
            list1.Add(index);
            list2.Add(index);
        }
Example #20
0
        //  implementation specific function-helper for better code re-use,
        //  it enables us to measure approximations errors in results
        static public void InterpolateSegments
        (
            List <RangeIndex> vec_ranges,
            List <LinearRegressionParams> vec_LR_params,
            List <double> data_x,
            //  results
            List <double> data_x_interpol,
            List <double> data_y_interpol
        )
        {
            data_x_interpol.Clear();
            data_y_interpol.Clear();

            int n_ranges = vec_ranges.Count;

            for (int i_rng = 0; i_rng < n_ranges; ++i_rng)
            {
                //  in the current range we only need to interpolate y-data
                //  using corresponding linear regression
                RangeIndex             range_i     = vec_ranges[i_rng];
                LinearRegressionParams lr_params_i = vec_LR_params[i_rng];

                double coef_a  = lr_params_i.coef_a;
                double coef_b  = lr_params_i.coef_b;
                int    i_start = range_i.idx_a;
                int    i_end   = range_i.idx_b;
                for (int i = i_start; i < i_end; ++i)
                {
                    double x_i = data_x[i];
                    double y_i = coef_a + coef_b * x_i;

                    data_x_interpol.Add(x_i);
                    data_y_interpol.Add(y_i);
                }
            }
        }
Example #21
0
        //  the function CanSplitRangeThorough()
        //  makes decision whether a given range should be split or not ;
        //
        //  a given range is not subdivided if the specified accuracy of
        //  linear regression has been achieved, otherwise, the function
        //  searches for the best split point in the range ;
        //
        static public bool CanSplitRangeThorough
        (
            //  original dataset
            List <double> data_x,
            List <double> data_y,
            //  the limit for maximum allowed approximation error (tolerance)
            double devn_max_user,
            //  input range to be split if linear regression is not acceptable
            RangeIndex idx_range_in,
            //  the position of a split point, when the function returns <true>
            ref int idx_split_out,
            //  the parameters of linear regression for the given range,
            //  when the function returns <false>
            LinearRegressionParams lr_params_out
        )
        {
            //  compute linear regression and approximation error for input range
            double error_range_in = double.MaxValue;

            ComputeLinearRegression(data_x, data_y, idx_range_in, lr_params_out, ref error_range_in);

            //  if the approximation is acceptable, input range is not subdivided
            if (error_range_in < devn_max_user)
            {
                return(false);
            }

            //  approximation error for a current split
            double err_split = double.MaxValue;
            //  the position (index) of a current split
            int idx_split  = -1;
            int idx_a      = idx_range_in.idx_a;
            int idx_b      = idx_range_in.idx_b;
            int end_offset = RangeLengthMin();

            //  sequential search for the best split point in the input range
            for (int idx = idx_a + end_offset; idx < idx_b - end_offset; ++idx)
            {
                //  sub-divided ranges
                RangeIndex range_left  = new RangeIndex(idx_a, idx);
                RangeIndex range_right = new RangeIndex(idx, idx_b);

                //  parameters of linear regression in sub-divided ranges
                LinearRegressionParams lin_regr_left  = new LinearRegressionParams(0.0, 0.0);
                LinearRegressionParams lin_regr_right = new LinearRegressionParams(0.0, 0.0);

                //  corresponding approximation errors
                double err_left  = double.MaxValue;
                double err_right = double.MaxValue;

                //  compute linear regression and approximation error in each range
                ComputeLinearRegression(data_x, data_y, range_left, lin_regr_left, ref err_left);
                ComputeLinearRegression(data_x, data_y, range_right, lin_regr_right, ref err_right);

                //  we use the worst approximation error
                double err_idx = Math.Max(err_left, err_right);
                //  the smaller error the better split
                if (err_idx < err_split)
                {
                    err_split = err_idx;
                    idx_split = idx;
                }
            }

            //  check that sub-division is valid,
            //  the case of short segment: 2 or 3 data points ;
            //  if (n==3) required approximation accuracy cannot be reached ;
            if (idx_split < 0)
            {
                return(false);
            }

            idx_split_out = idx_split;
            return(true);
        }
        public void RangeIndexConstructorUnitTest()
        {
            Assert.Inconclusive("TODO");

            var target = new RangeIndex();
        }
Example #23
0
        private static async Task CreateIndex(DocumentClient client, string collectionName)
        {
            Console.WriteLine("Set up Indexes");
            DocumentCollection collection =
                await
                client.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri(databaseId, collectionName));

            /*
             * Range over /prop/? (or /*) can be used to serve the following queries efficiently:
             * SELECT * FROM collection c WHERE c.prop = "value"
             * SELECT * FROM collection c WHERE c.prop > 5
             * SELECT * FROM collection c ORDER BY c.prop
             */
            Index indexNum = new RangeIndex(DataType.Number);

            collection.IndexingPolicy.IncludedPaths.Add(new IncludedPath()
            {
                Indexes = new Collection <Index>()
                {
                    indexNum
                },
                Path = @"/FamilyId/?"
            });

            /*
             * Hash over /prop/? (or /*) can be used to serve the following queries efficiently:
             * SELECT * FROM collection c WHERE c.prop = "value"
             */
            Index indexArray = new HashIndex(DataType.String);

            collection.IndexingPolicy.IncludedPaths.Add(new IncludedPath()
            {
                Indexes = new Collection <Index>()
                {
                    indexArray
                },
                Path = @"/Address/*"
            });

            /*
             * Hash over /props/[]/? (or /* or /props/*) can be used to serve the following queries efficiently:
             * SELECT tag FROM collection c JOIN tag IN c.props WHERE tag = 5
             */
            Index indexArr = new HashIndex(DataType.String);

            collection.IndexingPolicy.IncludedPaths.Add(new IncludedPath()
            {
                Indexes = new Collection <Index>()
                {
                    indexArr
                },
                Path = @"/Children/[]/?"
            });


            /* exclude from index Parents */
            collection.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath()
            {
                Path = @"/Parents/*"
            });


            await client.ReplaceDocumentCollectionAsync(collection);
        }
        /// <summary>
        /// Creates a new collection with the specified name or re-creates the collection if it already exists
        /// </summary>
        /// <param name="databaseId">Name of the Cosmos DB database within which to create or re-create the collection</param>
        /// <param name="collectionId">Name of the Cosmos DB collection to create or re-create</param>
        /// <param name="deleteExistingColl">Flag indicating whether or not to delete an exisitng collection</param>
        /// <returns></returns>
        private async Task CreateDocumentCollectionAsync(
            string databaseId,
            string collectionId,
            bool deleteExistingColl = true)
        {
            Database database = (await this.DocumentClient.ReadDatabaseAsync(string.Format("/dbs/{0}", databaseId))).Resource;

            if (database != null)
            {
                Console.WriteLine("Database with resourceid: {0} retrieved", database.ResourceId);
            }

            string partitionKey    = ConfigurationManager.AppSettings["CollectionPartitionKey"];
            int    offerThroughput = int.Parse(ConfigurationManager.AppSettings["CollectionThroughput"]);

            try
            {
                DocumentCollection existingColl = await this.DocumentClient.ReadDocumentCollectionAsync(string.Format("/dbs/{0}/colls/{1}", databaseId, collectionId));

                if (existingColl != null)
                {
                    if (!deleteExistingColl)
                    {
                        Console.WriteLine("Collection already present, returning...");
                    }
                    else
                    {
                        Console.WriteLine("Collection already present. Deleting collection...");
                        await this.DocumentClient.DeleteDocumentCollectionAsync(string.Format("/dbs/{0}/colls/{1}", databaseId, collectionId));

                        Console.WriteLine("Finished deleting the collection.");
                    }
                }
            }
            catch (DocumentClientException dce)
            {
                if (dce.StatusCode == HttpStatusCode.NotFound)
                {
                    Console.WriteLine("Collection not found, continuing as normal...");
                }
                else
                {
                    throw;
                }
            }

            RangeIndex     rangeIndexOverride1  = Index.Range(DataType.String, -1);
            RangeIndex     rangeIndexOverride2  = Index.Range(DataType.Number, -1);
            SpatialIndex   spatialIndexOverride = Index.Spatial(DataType.Point);
            IndexingPolicy indexingPolicy       = new IndexingPolicy(rangeIndexOverride1, rangeIndexOverride2, spatialIndexOverride);

            Console.WriteLine("Creating collection..");
            ResourceResponse <DocumentCollection> createResponse = null;

            PartitionKeyDefinition pkDefn = null;

            if (partitionKey != null)
            {
                Collection <string> paths = new Collection <string>();
                paths.Add(partitionKey);
                pkDefn = new PartitionKeyDefinition()
                {
                    Paths = paths
                };
            }
            if (pkDefn != null)
            {
                createResponse = await this.DocumentClient.CreateDocumentCollectionAsync(
                    database.SelfLink,
                    new DocumentCollection { Id = collectionId, IndexingPolicy = indexingPolicy, PartitionKey = pkDefn },
                    new RequestOptions { OfferThroughput = offerThroughput });
            }
            else
            {
                createResponse = await this.DocumentClient.CreateDocumentCollectionAsync(
                    database.SelfLink,
                    new DocumentCollection { Id = collectionId, IndexingPolicy = indexingPolicy },
                    new RequestOptions { OfferThroughput = offerThroughput });
            }

            Console.WriteLine("Successfully created the collection\n");
        }
Example #25
0
        //  the function SegmentedRegressionFast() implements
        //  algorithm for segmented linear (piecewise) regression,
        //  which uses for range splitting local maxima of
        //  absolute differences between original and smoothed values ;
        //  the method of smoothing is simple moving average;
        //
        //  the average performance of this algorithm is O(N logM), where
        //      N is the number of given values and
        //      M is the number of resulting line segments ;
        //  in the worst case the performace is quadratic ;
        //
        //  return value <false> shows that the required approximation accuracy
        //  has not been achieved ;
        //
        public bool SegmentedRegressionFast
        (
            //  input dataset:
            //  this function assumes that input x-data are equally spaced
            List <double> data_x,
            List <double> data_y,
            //  user specified approximation accuracy (tolerance) ;
            //  this parameter allows to control the total number
            //  and lengths of segments detected ;
            double devn_max,
            //  this parameter represents half length of window ( h_len+1+h_len ),
            //  which is used by simple moving average to create smoothed dataset
            int sm_half_len,
            //  the resulting segmented linear regression
            //  is interpolated to match and compare against input values
            List <double> data_x_res,
            List <double> data_y_res
        )
        {
            data_x_res.Clear();
            data_y_res.Clear();

            int size_x = data_x.Count;
            int size_y = data_y.Count;

            if (size_x != size_y)
            {
                return(false);
            }

            //  check for indivisible range
            if (size_x < 2 * RangeLengthMin())
            {
                return(false);
            }

            //  vector of smoothed values
            List <double> data_y_smooth = new List <double>();

            data_y_smooth.AddRange(data_y);
            SimpleMovingAverage(data_y_smooth, sm_half_len);

            //  vector of deviations (as absolute differences) between original and smoothed values
            List <double> vec_deviations = new List <double>();

            for (int i = 0; i < size_y; ++i)
            {
                vec_deviations.Add(Math.Abs(data_y_smooth[i] - data_y[i]));
            }

            //  find positions of local maxima in the vector of deviations
            List <int> vec_max_indices = new List <int>();

            FindLocalMaxima(vec_deviations, vec_max_indices);

            //  ranges (segments) of linear regression
            List <RangeIndex> vec_ranges = new List <RangeIndex>();
            //  parameters of linear regression in each matching range
            List <LinearRegressionParams> vec_LR_params = new List <LinearRegressionParams>();

            //  the stage of recursive top-down subvision:
            //  this processing starts from the entire range of given dataset
            RangeIndex range_top = new RangeIndex(0, size_x);
            //  the position (index) of a current split point
            int idx_split = -1;
            //  parameters of linear regression in a current range (segment)
            LinearRegressionParams lr_params = new LinearRegressionParams(0.0, 0.0);

            Stack <RangeIndex> stack_ranges = new Stack <RangeIndex>();

            stack_ranges.Push(range_top);

            while (stack_ranges.Count > 0)
            {
                range_top = stack_ranges.Pop();

                if (CanSplitRangeFast(data_x, data_y, vec_deviations, vec_max_indices,
                                      devn_max, range_top, ref idx_split, lr_params))
                {
                    //  reverse order of pushing onto stack eliminates re-ordering vec_ranges
                    //  after this function is completed
                    stack_ranges.Push(new RangeIndex(idx_split, range_top.idx_b));
                    stack_ranges.Push(new RangeIndex(range_top.idx_a, idx_split));
                }
                else
                {
                    //  the range is indivisible, we add it to the result
                    vec_ranges.Add(new RangeIndex(range_top.idx_a, range_top.idx_b));
                    vec_LR_params.Add(new LinearRegressionParams(lr_params.coef_a, lr_params.coef_b));
                }
            }


            //  interpolate the resulting segmented linear regression
            //  and verify the accuracy of the approximation
            List <double> data_x_interpol = new List <double>();
            List <double> data_y_interpol = new List <double>();

            InterpolateSegments(vec_ranges, vec_LR_params, data_x,
                                data_x_interpol, data_y_interpol);

            double appr_error = ApproximationErrorY(data_y, data_y_interpol);

            //if (appr_error > devn_max)
            //    return false;

            //  the result of this function when the required accuracy has been achieved
            data_x_res.AddRange(data_x_interpol);
            data_y_res.AddRange(data_y_interpol);

            return(true);
        }
Example #26
0
        //  the function CanSplitRangeFast()
        //  makes decision whether a given range should be split or not ;
        //
        //  a given range is not subdivided if the specified accuracy of
        //  linear regression has been achieved, otherwise,
        //  the function selects for the best split the position of
        //  the greatest local maximum of absolute differences
        //  between original and smoothed values in a given range ;
        //
        static public bool CanSplitRangeFast
        (
            //  original dataset
            List <double> data_x,
            List <double> data_y,
            //  absolute differences between original and smoothed values
            List <double> vec_devns_in,
            //  positions (indices) of local maxima in vec_devns_in
            List <int> vec_max_ind_in,
            //  the limit for maximum allowed approximation error (tolerance)
            double devn_max_user,
            //  input range to be split if linear regression is not acceptable
            RangeIndex idx_range_in,
            //  the position of a split point, when the function returns <true>
            ref int idx_split_out,
            //  the parameters of linear regression for the given range,
            //  when the function returns <false>
            LinearRegressionParams lr_params_out
        )
        {
            idx_split_out = -1;

            if (vec_devns_in.Count != data_x.Count)
            {
                Console.WriteLine("SLR: size error");
                return(false);
            }

            int end_offset = RangeLengthMin();
            int range_len  = idx_range_in.Length();

            if (range_len < end_offset)
            {
                Console.WriteLine("SLR: input range is too small");
                return(false);
            }

            //  compute linear regression and approximation error for input range
            double err_range_in = double.MaxValue;

            ComputeLinearRegression(data_x, data_y, idx_range_in, lr_params_out, ref err_range_in);

            //  if the approximation is acceptable, input range is not subdivided
            if (err_range_in < devn_max_user)
            {
                return(false);
            }

            //  check for indivisible range
            if (range_len < 2 * RangeLengthMin())
            {
                return(false);
            }

            if (vec_devns_in.Count == 0)
            {
                return(false);
            }

            //  for the main criterion of splitting here we use
            //  the greatest local maximum of deviations inside the given range
            int    idx_split_local_max = -1;
            double devn_max            = 0.0;
            double devn_cur            = 0.0;
            int    sz_loc_max          = vec_max_ind_in.Count;

            //  find inside given range local maximum with the largest deviation
            for (int k_max = 0; k_max < sz_loc_max; ++k_max)
            {
                int idx_max_cur = vec_max_ind_in[k_max];

                //  check if the current index is inside the given range and that
                //  potential split will not create segment with 1 data point only
                if ((idx_max_cur < idx_range_in.idx_a + end_offset) ||
                    (idx_max_cur >= idx_range_in.idx_b - end_offset))
                {
                    continue;
                }

                devn_cur = vec_devns_in[idx_max_cur];
                if (devn_cur > devn_max)
                {
                    devn_max            = devn_cur;
                    idx_split_local_max = idx_max_cur;
                }
            }

            //  the case of no one local maximum inside the given range
            if (idx_split_local_max < 0)
            {
                return(false);
            }

            //  the case (idx_split_local_max==0) is not possible here due to (end_offset==RANGE_LENGTH_MIN),
            //  this is a valid result ( idx_split_local_max > 0 )
            idx_split_out = idx_split_local_max;

            return(true);
        }
Example #27
0
        //  the function ComputeLinearRegression() computes parameters of
        //  linear regression and approximation error
        //  for a given range of a given dataset ;
        static public void ComputeLinearRegression
        (
            //  original dataset
            List <double> data_x,
            List <double> data_y,
            //  semi-open range [ a , b )
            RangeIndex idx_range,
            //  coefficients of linear regression in the given range
            LinearRegressionParams lin_regr_out,
            //  approximation error
            ref double err_appr_out
        )
        {
            if (idx_range.Length() < RangeLengthMin())
            {
                Console.WriteLine("SLR error: input range is too small");
                return;
            }

            int    idx_a  = idx_range.idx_a;
            int    idx_b  = idx_range.idx_b;
            double n_vals = idx_range.Length();
            double sum_x  = 0.0;
            double sum_y  = 0.0;
            double sum_xx = 0.0;
            double sum_xy = 0.0;

            //  compute the required sums:
            for (int it = idx_a; it < idx_b; ++it)
            {
                double xi = data_x[it];
                double yi = data_y[it];
                sum_x  += xi;
                sum_y  += yi;
                sum_xx += xi * xi;
                sum_xy += xi * yi;
            }

            //  compute parameters of linear regression in the given range
            if (!LinearRegressionParameters(n_vals, sum_x, sum_y, sum_xx, sum_xy, lin_regr_out))
            {
                //  this is a very unusual case for real data
                //Console.WriteLine("SLR: special case error");
                return;
            }

            double coef_a = lin_regr_out.coef_a;
            double coef_b = lin_regr_out.coef_b;

            //  use linear regression obtained to measure approximation error in the given range,
            //  the error is the maximum of absolute differences between original and approximation values
            double diff_max = 0.0;

            for (int it = idx_a; it < idx_b; ++it)
            {
                double xi      = data_x[it];
                double yi_orig = data_y[it];
                double yi_appr = coef_a + coef_b * xi;

                double diff_i = Math.Abs(yi_orig - yi_appr);
                if (diff_i > diff_max)
                {
                    diff_max = diff_i;
                }
            }

            err_appr_out = diff_max;
        }