def testOneSampleMatrix():
        EndPointSampler.cached=True
        nStates=2
        stationaryWeights = np.array((0.619, 0.592))
        bivariateWeights = 1.499
        bivariateFeatIndexDictionary = getHardCodedDictChainGraph(nStates=nStates)
        rateMtxObj = ReversibleRateMtxPiAndBinaryWeightsWithGraphicalStructure(nStates, stationaryWeights,
                                                                            bivariateWeights,
                                                                                bivariateFeatIndexDictionary)
        stationaryDist= rateMtxObj.getStationaryDist()
        rateMatrix = rateMtxObj.getRateMtx()
        T = 5.0

        pathStat2 = PathStatistics(nStates)

        postSampler = EndPointSampler(rateMatrix, T)
        fwdSampler = ForwardSimulation(T, rateMatrix)

        transition = np.zeros((nStates, nStates))
        sojournTime = np.zeros(nStates)

        nIters = 1000000
        for i in range(nIters):
            current = Path()
            prng = np.random.RandomState(i)
            startState = prng.choice(nStates, 1, replace=True, p=stationaryDist)
            curResult = fwdSampler.sampleStateTimeSeq(prng, startState)
            print(curResult['transitCount'])
            transition = transition + curResult["transitCount"]
            sojournTime = sojournTime + curResult["sojourn"]
            current.states = curResult["states"]
            current.times = curResult["time"]
            p2 = Path()
            postSampler.sample(np.random.RandomState(i + nIters), current.firstState(), current.lastState(), T, pathStat2, p2)
            print(i)

        m2 = pathStat2.getCountsAsSimpleMatrix() / nIters
        m1 = transition
        np.fill_diagonal(m1, sojournTime)
        m1 = m1 / nIters
        print(np.round(m1, 3))
        print(np.round(m2, 3))
    def testNonNormalizedGTRRateMtx():
        EndPointSampler.cached = True
        ## define a known rate matrix K80
        nStates = 4
        ## set a seed for the random generator
        np.random.seed(1)
        ## randomly generate a GTR rate matrix from the weights
        weights = np.random.normal(0, 1, 10)
        rateMtxObj = ReversibleRateMtx(nStates, weights)
        stationaryDist = rateMtxObj.getStationaryDist()

        k80 = ReversibleRateMtx(nStates, weights).getRateMtx()
        T = 3.0

        pathStat2 = PathStatistics(nStates)

        postSampler = EndPointSampler(k80, T)
        fwdSampler = ForwardSimulation(T, k80)

        transition = np.zeros((nStates, nStates))
        sojournTime = np.zeros(nStates)

        nIters = 1000000
        for i in range(nIters):
            current = Path()
            startState = np.argmax(np.random.multinomial(1, stationaryDist, 1))
            curResult = fwdSampler.sampleStateTimeSeq(startState)
            transition = transition + curResult["transitCount"]
            sojournTime = sojournTime + curResult["sojourn"]
            current.states = curResult["states"]
            current.times = curResult["time"]
            p2 = Path()
            postSampler.sample(np.random.RandomState(i + nIters), current.firstState(), current.lastState(), T, pathStat2, p2)
            print(i)

        m2 = pathStat2.getCountsAsSimpleMatrix() / nIters
        m1 = transition
        np.fill_diagonal(m1, sojournTime)
        m1 = m1 / nIters
        print(np.round(m1, 3))
        print(np.round(m2, 3))