示例#1
0
 public double GetDataSimple(GekkoTime_1_2 t)
 {
     //for Normal or Timeless series, not Light
     //if out of bounds, a NaN is returned, no error is issued
     //this is fine if it is not an expression, for instance if it is taken directly from a databank
     return(GetData(t));
 }
示例#2
0
 public int FromGekkoTimeToArrayIndex(GekkoTime_1_2 gt)
 {
     // ----------------------------------------------------------------------------
     // OFFSET SAFE: dataOffsetLag is handled in GetAnchorPeriodPositionInArray()
     // ----------------------------------------------------------------------------
     return(FromGekkoTimeToArrayIndexAbstract(gt, this.data.anchorPeriod, this.GetAnchorPeriodPositionInArray()));
 }
示例#3
0
        // -----------------------------------------------------------------------------
        // ----------------- private methods -------------------------------------------
        // -----------------------------------------------------------------------------


        //Not intended for outside use
        public int GetArrayIndex(GekkoTime_1_2 gt)
        {
            // ----------------------------------------------------------------------------
            // OFFSET SAFE: dataOffsetLag is handled in GetAnchorPeriodPositionInArray()
            // ----------------------------------------------------------------------------

            int rv = FromGekkoTimeToArrayIndexAbstract(gt, new GekkoTime_1_2(this.freq, this.data.anchorPeriod.super, this.data.anchorPeriod.sub), this.GetAnchorPeriodPositionInArray());

            return(rv);
        }
示例#4
0
        /// <summary>
        /// Gets the timeseries value corresponding to the given period.
        /// </summary>
        /// <param name="t">The period.</param>
        /// <returns>The value (double.NaN if missing)</returns>
        /// <exception cref="GekkoException">Exception if frequency of timeseries and period do not match.</exception>
        //smpl so that tooSmall/tooLarge error can be raised (set to null if irrelevant)
        //set smpl = null if tooSmall/tooLarge is irrelevant (no light series used)
        public double GetData(GekkoTime_1_2 t)
        {
            // ----------------------------------------------------------------------------
            // OFFSET SAFE: dataOffsetLag is handled in GetArrayIndex() which is safe
            // ----------------------------------------------------------------------------

            //Instead of GetData(null, t), please use GetDataNonLight(t)
            double rv = double.NaN;

            if (this.freq != t.freq)
            {
                FreqError(t);
            }
            if (this.data.GetDataArray_ONLY_INTERNAL_USE() == null)
            {
                //If no data has been added to the timeseries, NaN will always be returned.
                if (this.type == ESeriesType.ArraySuper)
                {
                    G.Writeln2("*** ERROR: The variable '" + this.name + "' is an array-timeseries,");
                    G.Writeln("           but is used as a normal timeseries here (without []-indexer)", Color.Red);
                    Program.ArrayTimeseriesTip(this.name);
                    throw new GekkoException();
                }
                else
                {
                    goto End;
                }
            }
            if (this.type == ESeriesType.Timeless)
            {
                rv = this.data.GetDataArray_ONLY_INTERNAL_USE()[0];
                goto End;
            }
            else
            {
                int index = GetArrayIndex(t);
                int tooSmall = 0; int tooLarge = 0;
                this.TooSmallOrTooLarge(index, out tooSmall, out tooLarge);
                if (tooSmall > 0 || tooLarge > 0)
                {
                    goto End;  //out of bounds, we return a missing value (NaN)
                }
                else
                {
                    rv = this.data.GetDataArray_ONLY_INTERNAL_USE()[index];
                    goto End;
                }
            }
End:
            //if (MissingZero(this))
            //{
            //    if (G.isNumericalError(rv)) rv = 0d;
            //}
            return(rv);
        }
示例#5
0
        private int ResizeDataArray(GekkoTime_1_2 gt, bool adjustStartEndDates)
        {
            // ----------------------------------------------------------------------------
            // OFFSET SAFE: dataOffsetLag is handled in GetArrayIndex() which is safe
            // ----------------------------------------------------------------------------

            int index = GetArrayIndex(gt);

            while (index < 0 || index >= this.data.GetDataArray_ONLY_INTERNAL_USE().Length)
            {
                //Resize data array
                //Keeps on going until the array is large enough.
                double   n            = Math.Max(this.data.GetDataArray_ONLY_INTERNAL_USE().Length, 4); //the length could be 1 (or maybe even 0), so we translate 0, 1, 2, 3 into 4 which will become 6 with 1.5 times expandRate.
                double[] newDataArray = new double[(int)(n * Globals.defaultExpandRateForDataArrays)];
                InitializeDataArray(newDataArray);
                if (index >= this.data.GetDataArray_ONLY_INTERNAL_USE().Length)
                {
                    //new periods after end
                    System.Array.Copy(this.data.GetDataArray_ONLY_INTERNAL_USE(), newDataArray, this.data.GetDataArray_ONLY_INTERNAL_USE().Length);
                }
                else
                {
                    //new periods added before start
                    int diffSize = newDataArray.Length - this.data.GetDataArray_ONLY_INTERNAL_USE().Length;
                    System.Array.Copy(this.data.GetDataArray_ONLY_INTERNAL_USE(), 0, newDataArray, diffSize, this.data.GetDataArray_ONLY_INTERNAL_USE().Length);
                    this.data.anchorPeriodPositionInArray += diffSize;
                    if (adjustStartEndDates)  //only for setting data
                    {
                        if (this.meta != null)
                        {
                            if (this.meta.firstPeriodPositionInArray != Globals.firstPeriodPositionInArrayNull)
                            {
                                this.meta.firstPeriodPositionInArray += diffSize;
                            }
                            if (this.meta.lastPeriodPositionInArray != Globals.lastPeriodPositionInArrayNull)
                            {
                                this.meta.lastPeriodPositionInArray += diffSize;
                            }
                        }
                    }
                }

                //this.data.GetDataArray_ONLY_FOR_INTERNAL_USE() = newDataArray;
                //this.data.SetDataArray_ONLY_FOR_INTERNAL_USE(newDataArray);

                this.data.SetDataarray_ONLY_INTERNAL_USE(newDataArray);
                index = GetArrayIndex(gt);
            }
            return(index);
        }
示例#6
0
        //NOT for outside use, note that it is not safe regarding .dataOffsetLag!
        private static int FromGekkoTimeToArrayIndexAbstract(GekkoTime_1_2 gt, GekkoTime_1_2 anchorPeriod, int anchorPeriodPositionInArray)
        {
            // ----------------------------------------------------------------------------
            // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            // !!! NOTE: OFFSET UNSAFE !!!!!!!!!
            // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            // ----------------------------------------------------------------------------

            //Static method not relying on the Series object
            //NO .dataOffsetLag here, must be added afterwards

            if (gt.freq != anchorPeriod.freq)
            {
                G.Writeln2("*** ERROR: Frequency mismatch");
                throw new GekkoException();
            }
            //this.anchorPeriod.sub is always 1 at the moment, and will always be 1 for Annual.
            //but we cannot count on anchorSubPeriod being 1 forever (for instance for daily obs)
            int rv = -12345;

            if (anchorPeriod.freq == EFreq_1_2.A)
            {
                //Special treatment in order to make it fast.
                //undated freq could return fast in the same way as this??
                rv = anchorPeriodPositionInArray + gt.super - anchorPeriod.super;
            }
            else
            {
                //Non-annual
                int subPeriods = 1;
                if (anchorPeriod.freq == EFreq_1_2.Q)
                {
                    subPeriods = 4;
                }
                else if (anchorPeriod.freq == EFreq_1_2.M)
                {
                    subPeriods = 12;
                }
                else if (anchorPeriod.freq == EFreq_1_2.U)
                {
                    subPeriods = 1;
                }
                //For quarterly data for instance, each super period amounts to 4 observations. Therefore the multiplication.
                int dif   = subPeriods * (gt.super - anchorPeriod.super) + (gt.sub - anchorPeriod.sub);
                int index = anchorPeriodPositionInArray + dif;
                rv = index;
            }

            return(rv);
        }
示例#7
0
        /// <summary>
        /// Gets the period (GekkoTime) corresponding to a particular index in the data array.
        /// </summary>
        /// <param name="indexInDataArray">The index in the data array.</param>
        /// <returns>The period (GekkoTime).</returns>
        public GekkoTime_1_2 GetPeriod(int indexInDataArray)
        {
            // ----------------------------------------------------------------------------
            // OFFSET SAFE: dataOffsetLag is handled in GetAnchorPeriodPositionInArray()
            // ----------------------------------------------------------------------------

            if (this.type == ESeriesType.Timeless)
            {
                G.Writeln2("*** ERROR: Timeless variable error #7");
                throw new GekkoException();
            }
            //The inverse method is GetArrayIndex()
            //Should maybe be private method? But then how to unit-test?
            //see also AddToPeriod()
            //DimensionCheck();
            int subPeriods = 1;

            if (this.freq == EFreq_1_2.Q)
            {
                subPeriods = 4;
            }
            else if (this.freq == EFreq_1_2.M)
            {
                subPeriods = 12;
            }
            else if (this.freq == EFreq_1_2.U)
            {
                subPeriods = 1;
            }

            //Calculates the period by means of using the anchor. Uses integer division, so there is an
            //implicit modulo calculation here.
            int sub1   = this.data.anchorPeriod.sub + (indexInDataArray - this.GetAnchorPeriodPositionInArray());
            int addPer = (sub1 - 1) / subPeriods;
            int addSub = (indexInDataArray - this.GetAnchorPeriodPositionInArray()) - subPeriods * addPer;

            int resultSuperPer = this.data.anchorPeriod.super + addPer;
            int resultSubPer   = this.data.anchorPeriod.sub + addSub;

            //This code below fixes a bug (1.4 suffers from it: only affects non-annual timeseries), bug fixed in 1.5.8
            if (resultSubPer < 1)  //this may happen, probaby because of "/" on integer not behaving as expected
            {
                resultSuperPer -= 1;
                resultSubPer   += subPeriods;
            }
            GekkoTime_1_2 t = new GekkoTime_1_2(this.freq, resultSuperPer, resultSubPer);

            return(t);
        }
示例#8
0
 private void InitDataArray(GekkoTime_1_2 t)
 {
     if (this.type == ESeriesType.Timeless)
     {
         G.Writeln2("*** ERROR: Timeless error #10");
         throw new GekkoException();
     }
     else
     {
         //The anchor is set in the middle of the array, and the anchor date is set to gt.
         this.data.SetDataarray_ONLY_INTERNAL_USE(new double[Globals.defaultPeriodsWhenCreatingTimeSeries]);
         this.data.anchorPeriodPositionInArray = Globals.defaultPeriodsWhenCreatingTimeSeries / 2; //possible to simulate 100 years forwards, and have data 100 years back.
         InitializeDataArray(this.data.GetDataArray_ONLY_INTERNAL_USE());                          //may fill it with NaN's
                                                                                                   //the following two will always be fixed to what they
                                                                                                   //were for the very first observation entering the double[] array (unless the array is resized).
         this.data.anchorPeriod = t;
     }
 }
示例#9
0
 private int ResizeDataArray(GekkoTime_1_2 gt)
 {
     return(ResizeDataArray(gt, true));
 }
示例#10
0
 private void FreqError(GekkoTime_1_2 t)
 {
     G.Writeln2("*** ERROR: Frequency mismatch: " + (this.freq.ToString()) + " versus " + (t.freq.ToString()));
     throw new GekkoException();
 }