public void AggregateLowestLevel(ICoverLevelResiduleInfo ResiduleInfo, ICoverLevelTermAriteInfo AriteInfo, ICoverState lowestLevelResiduleState,
                                         ICoverState lowestLevelAriteState, ICoverState ParentState, ICoverAllocationState lowestLevelaRiteAllocationRatio, ICoverAllocationState lowestLevelResidualAllocationRatio)
        {
            float[] ResiduleArr        = lowestLevelResiduleState.GetSubjectLoss();
            float[] aRiteArr           = lowestLevelAriteState.GetSubjectLoss();
            float[] parentArr          = ParentState.GetSubjectLoss();
            int[]   ResidulePartitions = ResiduleInfo.GetResiduleSubAggPartitions();
            int[]   AritePartitions    = AriteInfo.GetARiteAggregationPartitions();
            float[] aRiteRArr          = lowestLevelAriteState.GetSubjectLoss(); //TODO: this should be recoverables
            float[] residualRatio      = lowestLevelResidualAllocationRatio.GetCoverAllocationRatioP();
            float[] aRiteRatio         = lowestLevelaRiteAllocationRatio.GetCoverAllocationRatioP();

            //co-op factors
            float[]       aRiteFactors         = lowestLevelAriteState.GetFactors();    //AriteInfo.GetLowestCoverLevelInfo().LeafCoveraRiteFactors;
            float[]       residualRiteFactors  = lowestLevelResiduleState.GetFactors(); //ResiduleInfo.GetLowestCoverLevelInfo().LeafCoverResidualFactors;
            FactorPattern aRiteFPattern        = AriteInfo.GetLowestCoverLevelInfo().ApplyFactorPatternForaRite;
            FactorPattern residualRiteFPattern = ResiduleInfo.GetLowestCoverLevelInfo().ApplyFactorPatternForResidualRite;

            //pre-process
            float[] newResidualArr;
            float[] newaRiteArr;
            float[] newaRiteRArr;

            //TODO: tricky part, whether apply factor depending on if the allocated Rite recoverable is allocated from
            //summed term or PerRisk term. If allocated from summed term, no need apply factor again; if allocated
            //from PerRisk term, need apply factor
            //right now assuem all the top terms are either summed or PerRisk. This will make this temporarily implementation
            //easier. The Factor List is updated when forming LeafAriteFactor
            if (aRiteFPattern == FactorPattern.AllOnes)
            {
                newaRiteArr  = aRiteArr;
                newaRiteRArr = aRiteRArr;
            }
            else
            {
                newaRiteArr  = aRiteArr.Zip(aRiteFactors, (x1, x2) => x1 * x2).ToArray();
                newaRiteRArr = aRiteRArr.Zip(aRiteFactors, (x1, x2) => x1 * x2).ToArray();
            }

            if (residualRiteFPattern == FactorPattern.AllOnes)
            {
                newResidualArr = ResiduleArr;
            }
            else
            {
                newResidualArr = ResiduleArr.Zip(residualRiteFactors, (x1, x2) => x1 * x2).ToArray();
            }


            SumTwoArrayByPartition(newResidualArr, newaRiteArr, parentArr, ResidulePartitions, AritePartitions, newaRiteRArr, residualRatio, aRiteRatio);
        }
Esempio n. 2
0
        //public float Execute_For(int eventID, IVectorEvent Event)
        //{
        //    ILossState lossState = new LossState(Graph);

        //    GULossInputEngine inputEngine = new GULossInputEngine(lossState, Graph, Event);
        //    inputEngine.Run();

        //    //lowest level, no children
        //    int i = Graph.NumOfLevels - 1;
        //    ILevelFinancialInfo thisLevelInfo = Graph.GetTermLevelInfo(i);
        //    int lowestlevelsize = Graph.GetAggLevelInfo(i).LevelSize;
        //    float[] codeDed = thisLevelInfo.GetCodedMinDeds().ToArray();
        //    float[] codeLim = thisLevelInfo.GetCodedLimits().ToArray();

        //    //allLevelState[i] = new LevelState(thisLevelInfo.LevelSize);

        //    //int currSeed = 31 + eventID;
        //    //var RandGen = new Random(currSeed);

        //    if (!thisLevelInfo.HasMaxDed && !thisLevelInfo.HasPercentDed)
        //    {
        //        for (int j = 0; j < lowestlevelsize; j++)
        //        {
        //            allLevelState[i].SubjectLoss[j] = guloss;
        //            allLevelState[i].Excess[j] = Math.Max(0, guloss - codeLim[j]);
        //            allLevelState[i].Deductible[j] = Math.Min(guloss, codeDed[j]);
        //            allLevelState[i].Recoverable[j] = allLevelState[i].SubjectLoss[j] - allLevelState[i].Excess[j] - allLevelState[i].Deductible[j];
        //        }
        //    }

        //    //upper levels
        //    for (i = Graph.NumOfLevels - 2; i >= 0; i--)
        //    {
        //        thisLevelInfo = Graph.GetTermLevelInfo(i);
        //        ILevelInfo childLevelInfo = Graph.GetTermLevelInfo(i + 1);

        //        float[] dedFromBelow;
        //        float[] excessFromBelow;
        //        float[] subjectLossFromBelow;
        //        float[] recovFromBelow;

        //        bool SimplyCopy = false;
        //        if (SimplyCopy)
        //        {
        //            dedFromBelow = allLevelState[i + 1].Deductible;
        //            excessFromBelow = allLevelState[i + 1].Excess;
        //            subjectLossFromBelow = allLevelState[i + 1].SubjectLoss;
        //            recovFromBelow = allLevelState[i + 1].Recoverable;
        //        }
        //        else
        //        {
        //            dedFromBelow = Utilities.SumArrayByPartitionUsingFor(allLevelState[i + 1].Deductible, childLevelInfo.GetAggregationPartitions());
        //            excessFromBelow = Utilities.SumArrayByPartitionUsingFor(allLevelState[i + 1].Excess, childLevelInfo.GetAggregationPartitions());
        //            subjectLossFromBelow = Utilities.SumArrayByPartitionUsingFor(allLevelState[i + 1].SubjectLoss, childLevelInfo.GetAggregationPartitions());
        //            recovFromBelow = Utilities.SumArrayByPartitionUsingFor(allLevelState[i + 1].Recoverable, childLevelInfo.GetAggregationPartitions());
        //        }
        //        codeDed = thisLevelInfo.GetCodedMinDeds().ToArray();
        //        codeLim = thisLevelInfo.GetCodedLimits().ToArray();

        //        allLevelState[i] = new LevelState(thisLevelInfo.LevelSize);

        //        if (!thisLevelInfo.HasMaxDed && !thisLevelInfo.HasPercentDed)
        //        {
        //            for (int j = 0; j < thisLevelInfo.LevelSize; j++)
        //            {
        //                allLevelState[i].SubjectLoss[j] = subjectLossFromBelow[j];
        //                allLevelState[i].Excess[j] = Math.Max(excessFromBelow[j], Math.Max(0, subjectLossFromBelow[j] - codeLim[j]));
        //                allLevelState[i].Deductible[j] = Math.Max(dedFromBelow[j], Math.Min(subjectLossFromBelow[j], codeDed[j]));
        //                allLevelState[i].Recoverable[j] = allLevelState[i].SubjectLoss[j] - allLevelState[i].Excess[j] - allLevelState[i].Deductible[j];
        //                float deltaD = allLevelState[i].Deductible[j] - dedFromBelow[j];
        //                if (deltaD >= 0)
        //                {
        //                    allLevelState[i].AllocateRatioR[j] = 1 - deltaD / recovFromBelow[j];
        //                    allLevelState[i].AllocateRatioD[j] = 1;
        //                }
        //                else
        //                {
        //                    allLevelState[i].AllocateRatioR[j] = 1;
        //                    allLevelState[i].AllocateRatioD[j] = 1 - deltaD / dedFromBelow[j];
        //                }
        //            }
        //        }
        //    }
        //    Graph.AllLevelState = allLevelState;
        //    return allLevelState[0].Recoverable[0];
        //}


        //test:delete later

        //public float Run(IVectorEvent Event)
        public MatrixResultOutput Run(IVectorEvent Event)
        {
            MatrixResultOutput output = new MatrixResultOutput();

            //this is to store (utlitmately output) the total GU loss for all top Term Level SubjectLoss + LowestCoverLevel's ResidualRites SubjectLoss
            //the loss is accumulated throught each term level and the lowest cover level
            float TotalGULoss = 0;

            IniGraphState.Start();
            IGraphState graphState = new GraphState(Graph);

            IniGraphState.Stop();

            //Get GU
            AssignGUtoARite.Start();
            GULossInputEngine inputEngine = new GULossInputEngine(graphState, Graph, Event);

            inputEngine.Run();
            AssignGUtoARite.Stop();

            //Get Factors
            FactorInputEngine factorEngine = new FactorInputEngine(graphState, Graph, Event);

            factorEngine.Run();

            float[] FactorVector = Event.Factors;  //this is for TotalCoverState, only used to aggregate Cover Levels

            //If there is no term, only covers, we get lowest atomic rites, then return;
            //float topLevelPayout =0;
            if (Graph.NumOfLevels > 1)
            {
                //Check Contract level Ded and Sublimit Type (Absorbabel or Net of Deductible), and choose the correct Term Engine
                //which will have diff method to apply interaction
                bool        NetOfDeductible = Graph.ContractInfo.SublimitIsNetOfDeductible;
                bool        DedIsAbsorbable = Graph.ContractInfo.DedIsAbsorbable;
                ITermEngine TermEngine;

                if (NetOfDeductible && DedIsAbsorbable)
                {
                    TermEngine = new TermEngine1();
                }
                else if (!NetOfDeductible && !DedIsAbsorbable)
                {
                    TermEngine = new TermEngine4();
                }
                else if (NetOfDeductible && !DedIsAbsorbable)
                {
                    TermEngine = new TermEngine3();
                }
                else
                {
                    TermEngine = new TermEngine2();
                }


                #region Sunny Test max possible speed//// delete/comment out now! Or ask Sunny !!!!!!!

                //double[] covA_Alloc = ConverterForTestRun(graphState.GetARITELevelState(2).GetSubjectLoss());
                //double[] covC_Alloc = ConverterForTestRun(graphState.GetARITELevelState(3).GetSubjectLoss());

                //SunnyTesttimer.Start();
                ////double payout = TestRunDouble(covA_Alloc, covC_Alloc);
                //double payout = TestRun(graphState);
                //SunnyTesttimer.Stop();

                #endregion


                //Loop through all levels in Graph

                IAggregator Aggregator  = new Aggregator1();
                int         lowestlevel = Graph.LowestLevel;

                for (int i = lowestlevel; i > 0; i--)
                {
                    Aggregation.Start();

                    ILevelState          parentTermLevelState = graphState.GetTermLevelState(i - 1);
                    ILevelAtomicRITEInfo childaRITEInfo       = Graph.GetAtomicRITEInfo(i);
                    ISimpleLevelState    childaRITELevelState = graphState.GetARITELevelState(i);

                    //Aggregate level to parents
                    if (i == lowestlevel)
                    {
                        Aggregator.AggregateLevel(childaRITELevelState, parentTermLevelState, childaRITEInfo);
                        //TotalGULoss += childaRITELevelState.GetSubjectLoss().Zip(childaRITELevelState.GetFactors(), (x1, x2) => x1*x2).Sum();
                    }
                    else
                    {
                        ILevelNodeAggInfo childNodeAggInfo    = Graph.GetNodeAggInfo(i);
                        ILevelState       childTermLevelState = graphState.GetTermLevelState(i);
                        Aggregator.AggregateLevel(childTermLevelState, childaRITELevelState, parentTermLevelState, childNodeAggInfo, childaRITEInfo, aggregation1);
                        //TotalGULoss += childaRITELevelState.GetSubjectLoss().Zip(childaRITELevelState.GetFactors(), (x1, x2) => x1 * x2).Sum();
                    }
                    Aggregation.Stop();

                    //Do GULoss
                    if (i == 1)
                    {
                        TotalGULoss += parentTermLevelState.GetSubjectLoss().Zip(parentTermLevelState.GetFactors(), (x1, x2) => x1 * x2).Sum();
                    }

                    //Apply finacial terms to level
                    Interaction.Start();
                    ILevelFinancialInfo parentlevelFinInfo = Graph.GetTermLevelInfo(i - 1);
                    ILevelNodeAggInfo   parentlevelaggInfo = Graph.GetNodeAggInfo(i - 1);
                    bool HasMaxDed    = Graph.GetTermLevelInfo(i - 1).HasMaxDed;
                    bool HasFranchise = Graph.GetTermLevelInfo(i - 1).HasFranchiseDed;

                    if (i == lowestlevel)
                    {
                        TermEngine.InteractionOnLowestTermLevel(parentTermLevelState, parentlevelFinInfo, parentlevelaggInfo.NumOfNodes);
                    }
                    else
                    {
                        TermEngine.ApplyInteraction(parentTermLevelState, parentlevelFinInfo, parentlevelaggInfo.NumOfNodes);
                    }

                    Interaction.Stop();
                }


                //float topLevelPayout = graphState.GetTermLevelState(0).GetRecoverable()[0];
                //topLevelPayout = graphState.GetTermLevelState(0).GetRecoverable().Sum();

                //Allocate & loop through each level to get AriteR
                MatrixGraphAllocation Allocator = new MatrixGraphAllocation(Graph, graphState);
                allocationtimer.Start();
                Allocator.Run();
                allocationtimer.Stop();

                //float AllocatedFinalPayout = 0;

                //for (int i = 0; i <= lowestlevel; i++)
                //{
                //    float[] AriteR = graphState.GetARITELevelState(i).GetRecoverable();
                //    AllocatedFinalPayout += AriteR.Sum();
                //}
                //topLevelPayout = AllocatedFinalPayout;
            }
            //else
            //{
            //    ISimpleLevelState childaRITELevelState = graphState.GetARITELevelState(0);
            //    topLevelPayout = childaRITELevelState.GetSubjectLoss().Sum();

            //}

            //Execute covers after terms:
            int lowestCoverLevel = Graph.LowestCoverLevel;
            int NumOfCoverLevels = Graph.NumOfCoverLevels;
            ICoverLevelResiduleInfo  ResiduleInfo = Graph.GetCoverResiduleInfo();
            ICoverLevelTermAriteInfo AriteInfo    = Graph.GetCoverAriteInfo();
            ICoverState      ResiduleState        = graphState.GetLowestCoverLevelResiduleState();
            ICoverState      AriteState           = graphState.GetLowestCoverLevelAriteState();
            ICoverState      TotalCoverState      = graphState.GetTotalCoverState();
            ICoverAggregator CoverAggregator      = new CoverAggregator();

            //int StartPosition=0;
            //int EndPosition = Graph.GetCoverNodeAggInfo(Graph.LowestCoverLevel).NumOfNodes;
            int   CalculationStartPosition = 0;
            int   ParentStartPosition      = Graph.GetCoverNodeAggInfo(Graph.LowestCoverLevel + 1).NumOfNodes;
            int   TopCoverLevel            = lowestCoverLevel + NumOfCoverLevels;
            float TotalPayout = 0;

            //Get Subject Loss for the lowest cover level (GU & Recoverable)
            CoverInputEngine CoverinputEngine = new CoverInputEngine(graphState, Graph, Event);
            CoverinputEngine.Run();


            for (int i = lowestCoverLevel; i < TopCoverLevel; i++)
            {
                //Aggregation:
                if (i == lowestCoverLevel)
                {
                    CoverAggregator.AggregateLowestLevel(ResiduleInfo, AriteInfo, ResiduleState, AriteState, TotalCoverState, graphState.GetLowestCoverLevelAriteAllocationRatio(), graphState.GetLowestCoverLevelResidualAllocationRatio());
                    TotalGULoss += ResiduleState.GetSubjectLoss().Zip(ResiduleState.GetFactors(), (x1, x2) => x1 * x2).Sum();
                }
                else
                {
                    ICoverAllocationState         currLevelAllocationRatio = graphState.GetCoverLevelAllocationRatioState(i);
                    ICoverLevelNodeAggInfo        ChildrenLevelAggInfo     = Graph.GetCoverNodeAggInfo(i);
                    IDerivedCoverLevelNodeAggInfo DerivedInfo = Graph.GetDerivedCoverNodeAggInfo(i + 1);
                    CoverAggregator.AggregateLevel(ParentStartPosition, TotalCoverState, ChildrenLevelAggInfo, DerivedInfo, currLevelAllocationRatio, FactorVector);

                    ParentStartPosition += Graph.GetCoverNodeAggInfo(i + 1).NumOfNodes;
                }

                //Apply Financial Terms to parent level
                ICoverLevelFinancialInfo ParentLevelFinInfo = Graph.GetCoverLevelInfo(i + 1);
                ICoverEngine             CoverEngine        = new CoverEngine();

                int[] LeafTopCoverList = Graph.GetCoverNodeAggInfo(lowestCoverLevel + 1).GetLeafTopCoverList();
                if (i != TopCoverLevel - 1)
                {
                    CoverEngine.ApplyCoverLayer(ParentLevelFinInfo, CalculationStartPosition, TotalCoverState);
                }
                else
                {
                    TotalPayout = CoverEngine.ApplyTopCoverLayer(ParentLevelFinInfo, CalculationStartPosition, TotalCoverState, LeafTopCoverList, FactorVector);
                }

                //Reset Position for next loop
                CalculationStartPosition = ParentStartPosition;
            }

            //Allocate cover graph payout
            coverAllocationtimer.Start();
            MatrixCoverGraphAllocation CoverAllocator = new MatrixCoverGraphAllocation(Graph, graphState);
            CoverAllocator.Run();
            coverAllocationtimer.Stop();

            output.TotalGULoss = TotalGULoss;
            output.TotalPayOut = TotalPayout;

            //combine allocated Residual loss&indicies and Arite loss&indicies for output
            output.RiteGULossIndicies  = (Graph.GetCoverAriteInfo().GetAriteGULossIndicies()).Concat(Graph.GetCoverResiduleInfo().GetGULossIndicies()).ToArray();
            output.AllocatedRitePayout = (graphState.GetLowestCoverLevelAriteState().GetAllocatedPayout()).Concat(graphState.GetLowestCoverLevelResiduleState().GetAllocatedPayout()).ToArray();

            return(output);

            //return TotalPayout;

            //return topLevelPayout;

            //Need to get Final Payout for cover....
            #region Delete Later

            //allLevelState[i] = new LevelState(thisLevelInfo.LevelSize);
            //int currSeed = 31 + eventID;
            //var RandGen = new Random(currSeed);

            //float[] subjectloss = new float[thisLevelSize];
            //Array.Copy(Graph.AllLevelState[lowestlevel].SubjectLoss, subjectloss, thisLevelSize);
            //float[] excess = new float[thisLevelSize];
            //float[] ded = new float[thisLevelSize];
            //float[] recov = new float[thisLevelSize];

            //if (!thisLevelInfo.HasMaxDed && !thisLevelInfo.HasPercentDed)
            //{
            //    for (int j = 0; j < thisLevelSize; j++)
            //    {
            //        //float guloss = (float)(RandGen.NextDouble());
            //        //guloss = guloss * 1000000;
            //        //float guloss = Event.LossVector[thisLevelInfo.GetAtomicRITEIndicies().ToArray()[j]];

            //        float guloss = subjectloss[j];
            //        excess[j] = Math.Max(0, guloss - codeLim[j]);
            //        ded[j] = Math.Min(guloss, codeDed[j]);
            //        recov[j] = subjectloss[j] - excess[j] - ded[j];
            //        //allLevelState[i].SubjectLoss[j] = guloss;
            //        //allLevelState[i].Excess[j] = Math.Max(0, guloss - codeLim[j]);
            //        //allLevelState[i].Deductible[j] = Math.Min(guloss, codeDed[j]);
            //        //allLevelState[i].Recoverable[j] = allLevelState[i].SubjectLoss[j] - allLevelState[i].Excess[j] - allLevelState[i].Deductible[j];
            //    }
            //    Array.Copy(subjectloss, allLevelState[lowestlevel].SubjectLoss, thisLevelSize);
            //    Array.Copy(excess, allLevelState[lowestlevel].Excess, thisLevelSize);
            //    Array.Copy(ded, allLevelState[lowestlevel].Deductible, thisLevelSize);
            //    Array.Copy(recov, allLevelState[lowestlevel].Recoverable, thisLevelSize);
            //}


            //    thisLevelInfo = Graph.GetTermLevelInfo(i);
            //    ILevelInfo childLevelInfo = Graph.GetTermLevelInfo(i + 1);
            //    thisLevelSize = thisLevelInfo.LevelSize;

            //    float[] dedFromBelow;
            //    float[] excessFromBelow;
            //    float[] subjectLossFromBelow;
            //    float[] recovFromBelow;
            //    float[] rRatio = new float[thisLevelSize];
            //    float[] dRatio = new float[thisLevelSize];

            //    subjectloss = new float[thisLevelSize];
            //    excess = new float[thisLevelSize];
            //    ded = new float[thisLevelSize];
            //    recov = new float[thisLevelSize];

            //    bool SimplyCopy = true;
            //    if (SimplyCopy)
            //    {
            //        dedFromBelow = allLevelState[i + 1].Deductible;
            //        excessFromBelow = allLevelState[i + 1].Excess;
            //        subjectLossFromBelow = allLevelState[i + 1].SubjectLoss;
            //        recovFromBelow = allLevelState[i + 1].Recoverable;
            //    }
            //    else
            //    {
            //        dedFromBelow = SumArrayByPartition(allLevelState[i + 1].Deductible, childLevelInfo.GetAggregationPartitions());
            //        excessFromBelow = SumArrayByPartition(allLevelState[i + 1].Excess, childLevelInfo.GetAggregationPartitions());
            //        subjectLossFromBelow = SumArrayByPartition(allLevelState[i + 1].SubjectLoss, childLevelInfo.GetAggregationPartitions());
            //        recovFromBelow = SumArrayByPartition(allLevelState[i + 1].Recoverable, childLevelInfo.GetAggregationPartitions());
            //    }



            //    codeDed = thisLevelInfo.GetCodedMinDeds().ToArray();
            //    codeLim = thisLevelInfo.GetCodedLimits().ToArray();

            //    allLevelState[i] = new LevelState(thisLevelInfo.LevelSize);

            //    if (!thisLevelInfo.HasMaxDed && !thisLevelInfo.HasPercentDed)
            //    {
            //        for (int j = 0; j < thisLevelSize; j++)
            //        {
            //            subjectloss[j] = subjectLossFromBelow[j];
            //            excess[j] = Math.Max(excessFromBelow[j], Math.Max(0, subjectLossFromBelow[j] - codeLim[j]));
            //            ded[j] = Math.Max(dedFromBelow[j], Math.Min(subjectLossFromBelow[j], codeDed[j]));
            //            recov[j] = subjectloss[j] - excess[j] - ded[j];

            //            float deltaD = allLevelState[i].Deductible[j] - dedFromBelow[j];
            //            if (deltaD >= 0)
            //            {
            //                rRatio[j] = 1 - deltaD / recovFromBelow[j];
            //                dRatio[j] = 1;
            //            }
            //            else
            //            {
            //                rRatio[j] = 1;
            //                dRatio[j] = 1 - deltaD / dedFromBelow[j];
            //            }
            //        }
            //        Array.Copy(subjectloss, allLevelState[i].SubjectLoss, thisLevelSize);
            //        Array.Copy(excess, allLevelState[i].Excess, thisLevelSize);
            //        Array.Copy(ded, allLevelState[i].Deductible, thisLevelSize);
            //        Array.Copy(recov, allLevelState[i].Recoverable, thisLevelSize);
            //        Array.Copy(rRatio, allLevelState[i].AllocateRatioR, thisLevelSize);
            //        Array.Copy(dRatio, allLevelState[i].AllocateRatioD, thisLevelSize);
            //    }
            //}
            //Array.Copy(allLevelState, Graph.AllLevelState, Graph.NumOfLevels);
            #endregion
        }