private void AllocateToOneTermLevel()
        {
            int NumOfArites = ChildrenLevelAriteState.GetSubjectLoss().Length;

            if (NumOfArites != 0)
            {
                AllocateToTermAndArite();
            }
            else
            {
                AllocateToTermOnly();
            }
        }
        private void AllocateToLowestLevel()
        {
            float[] ParentR           = ParentTermLevelState.GetRecoverable();
            float[] ParentS           = ParentTermLevelState.GetSubjectLoss();
            float[] ChildrenS         = ChildrenLevelAriteState.GetSubjectLoss();
            float[] ChildrenR         = ChildrenLevelAriteState.GetRecoverable();
            int[]   ChildrenPartition = ChildrenLevelAriteInfo.GetARiteAggregationPartitions();
            int     NumOfParents      = ParentR.Length;
            float   AllocationRatio;
            int     EndPosition;

            int StartPosition = 0;

            for (int i = 0; i < NumOfParents; i++)
            {
                EndPosition = ChildrenPartition[i];
                if (ParentR[i] == 0)
                {
                    Array.Clear(ChildrenR, StartPosition, EndPosition - StartPosition);
                    StartPosition = EndPosition;
                    continue;
                }

                //ParentS[i] is equivalent to the sum of the Rs from children below;
                //AllocationRatio = ParentR[i]/ ParentS[i]; //this parent Subject has already co-op with factors, but the Children are not
                float lossTotal = 0;

                for (int j = StartPosition; j < EndPosition; j++)
                {
                    //ChildrenR[j] = ParentR[i] * (ChildrenS[j] / ParentS[i]);
                    //ChildrenR[j] = AllocationRatio * ChildrenS[j];
                    lossTotal += ChildrenS[j];
                }
                for (int j = StartPosition; j < EndPosition; j++)
                {
                    ChildrenR[j] = ParentR[i] * ChildrenS[j] / lossTotal;
                }
                //TODO: to merge the two for loops to one

                StartPosition = EndPosition;
            }
        }
        private void AllocateToTermAndArite()
        {
            float[] ParentR           = ParentTermLevelState.GetRecoverable();
            float[] ChildrenR         = ChildrenTermLevelState.GetRecoverable();
            float[] ChildrenD         = ChildrenTermLevelState.GetDeductible();
            float[] ChildrenS         = ChildrenTermLevelState.GetSubjectLoss();
            float[] ChildrenX         = ChildrenTermLevelState.GetExcess();
            int[]   ChildrenPartition = ChildrenLevelAggInfo.GetNodeAggregationPartitions();
            int     NumOfParents      = ParentR.Length;

            float[] ARiteR         = ChildrenLevelAriteState.GetRecoverable();
            float[] ARiteS         = ChildrenLevelAriteState.GetSubjectLoss();
            int[]   AritePartition = ChildrenLevelAriteInfo.GetARiteAggregationPartitions();

            float[] rRatio = ParentTermLevelState.GetAllocateRatioR();
            float[] dRatio = ParentTermLevelState.GetAllocateRatioD();
            float   allocatedRSummed;
            float   originalRSummed;
            float   temp;
            float   DRatio;
            float   RRatio;

            //Allocation one parent level to its children level
            int StartPosition      = 0;
            int AriteStartPosition = 0;

            for (int i = 0; i < NumOfParents; i++)
            {
                int EndPosition      = ChildrenPartition[i];
                int AriteEndPosition = AritePartition[i];
                if (ParentR[i] == 0)
                {
                    Array.Clear(ChildrenR, StartPosition, EndPosition - StartPosition);
                    Array.Clear(ARiteR, AriteStartPosition, AriteEndPosition - AriteStartPosition);
                    StartPosition      = EndPosition;
                    AriteStartPosition = AriteEndPosition;
                    continue;
                }

                allocatedRSummed = 0;
                originalRSummed  = 0;
                temp             = 0;
                DRatio           = dRatio[i];
                RRatio           = rRatio[i];

                for (int c = StartPosition; c < EndPosition; c++)
                {
                    //ChildrenD[c] = dRatio[i] * ChildrenD[c];
                    //originalRSummed += ChildrenR[c];
                    //ChildrenR[c] = (ChildrenS[c] - ChildrenX[c] - ChildrenD[c]) * rRatio[i];
                    //ChildrenD[c] = ChildrenS[c] - ChildrenX[c] - ChildrenR[c];
                    //allocatedRSummed += ChildrenR[c];
                    temp              = ChildrenS[c] - ChildrenX[c];
                    ChildrenD[c]      = DRatio * ChildrenD[c];
                    originalRSummed  += ChildrenR[c];
                    ChildrenR[c]      = (temp - ChildrenD[c]) * RRatio;
                    ChildrenD[c]      = temp - ChildrenR[c];
                    allocatedRSummed += ChildrenR[c];
                }

                for (int j = AriteStartPosition; j < AriteEndPosition; j++)
                {
                    //originalRSummed += ARiteR[j];
                    originalRSummed  += ARiteS[j];
                    ARiteR[j]         = ARiteS[j] * RRatio;
                    allocatedRSummed += ARiteR[j];
                }


                //when this parent j is done
                if (allocatedRSummed == 0)
                {
                    for (int c = StartPosition; c < EndPosition; c++)
                    {
                        ChildrenR[c] = ParentR[i] * ChildrenR[c] / originalRSummed;
                    }
                    for (int j = AriteStartPosition; j < AriteEndPosition; j++)
                    {
                        ARiteR[j] = ParentR[i] * ARiteR[j] / originalRSummed;
                    }
                }
                else
                {
                    //Nina: create temp to improve performance so that ParentR[i] / allocatedRSummed won't
                    //be calculated many times in for loop below;
                    temp = ParentR[i] / allocatedRSummed;
                    for (int c = StartPosition; c < EndPosition; c++)
                    {
                        //ChildrenR[c] = ParentR[i] * ChildrenR[c] / allocatedRSummed;
                        ChildrenR[c] = temp * ChildrenR[c];
                    }
                    for (int j = AriteStartPosition; j < AriteEndPosition; j++)
                    {
                        //ARiteR[j] = ParentR[i] * ARiteR[j] / allocatedRSummed;
                        ARiteR[j] = temp * ARiteR[j];
                    }
                }
                StartPosition      = EndPosition;
                AriteStartPosition = AriteEndPosition;
            }
        }