def myDiscreteRandom3():
    if belongs(random(), 0, 0.3333):
        return 1
    elif belongs(random(), 0.3333, 0.6666):
        return 2
    else:
        return 3
def move3(cfg, nSteps, Emin, Em, Emplus1, L):
    hasMoved = False
    acceptances = 0
    [I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty] = [0, 0, 0]
    Eold = model.getEnergy(cfg)
    for i in range(nSteps):
        # iAtom, idim, l = s(6, L)
        if hasMoved:
            hasMoved = False
            Eold = e
        #
        cfgTemp = getMove3(cfg)
        e = model.getEnergy(cfgTemp)
        if (e <= Emplus1):
            hasMoved = True
            cfg = copy.deepcopy(cfgTemp)
            acceptances += 1  # accepted move.
            draw(cfg.positions, e)
            cfg.translate(-cfg.get_center_of_mass())

        else:
            e = Eold
        #
        if belongs(
                e, Emin, Em
        ):  # (Emin <= e <= E[m - 1]): #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            I_EminToEm += 1  # un gol más para ∫_Emin^Em-1 Ω(E)dE
        elif belongs(e, Em, Emplus1):  # (E[m - 1] <= e <= Em):
            I_EmToEmplus1 += 1  # un gol más para ∫_Em-1^Em Ω(E)dE
        elif Emplus1 < e:
            I_Emplus1ToInfty += 1
        #
    #
    ratioAcceptances = float(
        acceptances
    ) / nSteps  #`float()` to ensure the division will be a float (python2 resembles Fortran in divisions)

    if I_EminToEm == 0:
        I_EminToEm = 1
    alpha = I_EmToEmplus1 / float(
        I_EminToEm
    )  # `float()` to ensure the division will be a float (python2 resembles Fortran in divisions)
    print("alpha = ", float("{0:.3f}".format(alpha)))
    print(float("{0:.3f}".format(ratioAcceptances)), I_EminToEm, I_EmToEmplus1,
          I_Emplus1ToInfty, "...", L)
    return alpha, ratioAcceptances
def move(X, sigma, epsilon, rcut, nSteps, Emin, Em, Emplus1, L):
    hasMoved = False
    acceptances = 0
    [I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty] = [0, 0, 0]
    Eold = cf.getLJenergy(X, sigma, epsilon)
    # acceptances
    # I_EminToEm
    # I_EmToEmplus1
    for i in range(nSteps):
        # iAtom = i % len(X)
        # iAtom = int(random() * len(X))
        # idim  = int(random() * 6)

        # get a configuration e,X after randomly move X:
        # Eold = getEnergyConfig(X)
        # assert( Eo == getEnergyConfig(X) )

        iAtom, idim, l = s(6, L)

        if hasMoved:
            hasMoved = False
            Eold = e
        #
        # Xt = copy.deepcopy(X)

        # d = Vector3(getRandomWalk(L), getRandomWalk(L), getRandomWalk(L))
        # d = unitVect(idim) * getRandomWalk(L)
        d = unitVect2(idim) * L * (random() - 0.5)
        # d = unitVect2(idim) * l

        ########################################################################
        Xt[iAtom] += d
        ########################################################################

        ########################################################################
        #
        getForceMatrix = False
        #
        if use_mtp:
            e, eigenvalues = cf.getLJeigenvalues2(Xt, epsilon, sigma, rcut,
                                                  getForceMatrix, aCell)
        elif use_aseLJ:
            e, eigenvalues = cf.getLJeigenvalues(Xt, epsilon, sigma, rcut,
                                                 getForceMatrix)
        #
        # e  = cf.getLJenergy(Xt, sigma, epsilon)

        # P_old2new = mc.getProbTransition(e, Eold, Em, EmMinus1)
        # P_old2new = mc.getProbTransition(e, Eold, Emplus1 + 0.0004, Em)
        # P_old2new = mc.getProbTransition(e, Eold, Emplus1, Em)

        # os.system("echo "+ str(e) + " >> out2.txt")

        # if (e <= Emplus1 + 0.001):
        # if (e <= Emplus1 + 0.0006):
        # if (e <= Emplus1 + 0.0002):
        if (e <= Emplus1):
            # if ( P_old2new >= random() ):
            # os.system("echo "+ str(e) + " >> out.txt")
            hasMoved = True
            # X = copy.deepcopy(Xt)
            X[iAtom] += d
            acceptances += 1  # accepted move.
            draw(X, e)
            X = maintainCenterOfMass(X)
        else:
            e = Eold
        #

        # # it has no sense to add the same configuration (not moved) to Ω:
        # if hasMoved:
        #     acceptances += 1 # accepted move.
        # #
        if belongs(
                e, Emin, Em
        ):  # (Emin <= e <= E[m - 1]): #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            I_EminToEm += 1  # un gol más para ∫_Emin^Em-1 Ω(E)dE
        elif belongs(e, Em, Emplus1):  # (E[m - 1] <= e <= Em):
            I_EmToEmplus1 += 1  # un gol más para ∫_Em-1^Em Ω(E)dE
        elif Emplus1 < e:
            I_Emplus1ToInfty += 1
        #
    #
    ratioAcceptances = float(
        acceptances
    ) / nSteps  #`float()` to ensure the division will be a float (python2 resembles Fortran in divisions)

    if I_EminToEm == 0:
        I_EminToEm = 1
    alpha = I_EmToEmplus1 / float(
        I_EminToEm
    )  # `float()` to ensure the division will be a float (python2 resembles Fortran in divisions)
    print("alpha = ", float("{0:.3f}".format(alpha)))
    print(float("{0:.3f}".format(ratioAcceptances)), I_EminToEm, I_EmToEmplus1,
          I_Emplus1ToInfty, "...", L)
    # acceptances
    # I_EminToEm
    # I_EmToEmplus1
    ################################################################################

    # log_idos.append( log_sum_idos + log(alpha) ) # =log_idos[m]
    #
    # # calculate log_sum_idos:
    # # Log of the sum of integrals for each interval, m=1, m=2, m=3,...
    # DOSintegrals = [ exp(log_int) for log_int in log_idos ]
    # log_sum_idos = log(sum(DOSintegrals))
    #
    # return alpha, log_idos, log_sum_idos, L
    # return alpha
    return alpha, ratioAcceptances
def move2(X, sigma, epsilon, rcut, nSteps, Emin, Em, Emplus1, L):
    hasMoved = False
    acceptances = 0
    [I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty] = [0, 0, 0]
    Eold = cf.getLJenergy(X, sigma, epsilon)
    for i in range(nSteps):
        # iAtom, idim, l = s(6, L)
        if hasMoved:
            hasMoved = False
            Eold = e
        #
        # d = unitVect2(idim) * L * (random() - 0.5)
        ########################################################################
        Xt, St = getMove(nAtoms, X, canSwap, neighbors,
                         S)  #move includes translation or swap
        # Xt[iAtom] += d
        ########################################################################

        ########################################################################
        #
        getForceMatrix = False
        #
        if use_mtp:
            e, eigenvalues = cf.getLJeigenvalues2B(Xt, St, epsilon, sigma,
                                                   rcut, getForceMatrix, aCell)
        elif use_aseLJ:
            e, eigenvalues = cf.getLJeigenvaluesB(Xt, St, epsilon, sigma, rcut,
                                                  getForceMatrix)
        #
        if (e <= Emplus1):
            hasMoved = True
            # X = copy.deepcopy(Xt)

            # X[iAtom] += d
            # X = copy.deepcopy(Xt)
            # S = copy.deepcopy(St)
            X = Xt  # ???????????????????????????????????????????????????????????
            S = St

            acceptances += 1  # accepted move.
            draw(X, e)
            X = maintainCenterOfMass(X)
        else:
            e = Eold
        #
        #
        if belongs(
                e, Emin, Em
        ):  # (Emin <= e <= E[m - 1]): #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            I_EminToEm += 1  # un gol más para ∫_Emin^Em-1 Ω(E)dE
        elif belongs(e, Em, Emplus1):  # (E[m - 1] <= e <= Em):
            I_EmToEmplus1 += 1  # un gol más para ∫_Em-1^Em Ω(E)dE
        elif Emplus1 < e:
            I_Emplus1ToInfty += 1
        #
    #
    ratioAcceptances = float(
        acceptances
    ) / nSteps  #`float()` to ensure the division will be a float (python2 resembles Fortran in divisions)

    if I_EminToEm == 0:
        I_EminToEm = 1
    alpha = I_EmToEmplus1 / float(
        I_EminToEm
    )  # `float()` to ensure the division will be a float (python2 resembles Fortran in divisions)
    print("alpha = ", float("{0:.3f}".format(alpha)))
    print(float("{0:.3f}".format(ratioAcceptances)), I_EminToEm, I_EmToEmplus1,
          I_Emplus1ToInfty, "...", L)
    return alpha, ratioAcceptances
def randomMCmovesParallel2(Eminimo, E_mMinus2, E_mMinus1, E_m,\
                  nSteps, e, X, L, structEq, Xeq, forceMatrix):
    import copy
    import harmonic as ha
    print("Emin, E_m2, E_m1, E_m = ", Eminimo, E_mMinus2, E_mMinus1, E_m)

    lCfgs = [] # to save cfgs for the next subdivision.
    # where: lCfgs_m = [cfg_1, cfg_2, ..., cfg_i, ...]
    # where: cfg_i = [energy_i, X_i ]
    # where: cfg_i = [energy_i, X_i ]
    # where: X_i = [r1, r2, r3, r4, ..., rNatoms]
    # where: r_n = [x,y,z]

    #===========================================================================
    # paper: "The maximum displacement of the translational moves is
    # automatically changed after each partitioning process to adjust the
    # acceptance toward the range 25%–35%. If the acceptance rate during a
    # partitioning process falls below 10% or above 70%, the partitioning
    # process is repeated."
    # L ~amplitud of random walk of a ...
    #             ...particle (dx,dy,dz) = (L*random(), L*random(), L*random())
    ratioOfCfgsToSave = 0.5
    ratioAcceptances  = 0
    # L      = 0.1
    repMax = 1 #10 # maximum number of repetitions to get the appropriate ratio of
               # acceptances at a certain L value.
    repeat = 0

    ratioMin = 0.25
    ratioMax = 0.35

    while( (not belongs(ratioAcceptances, ratioMin, ratioMax) and\
            (repeat < repMax) ) or\
            continuar):
        continuar = False

        [I1, I2] = [0, 0]
        repeat += 1
        acceptances = 0

        # Collect ehist for [Emin,E[m-1]] and [E[m-1],Em]:
        for i in range(nSteps):
            # get a configuration e,X after randomly move X:

            e, X, hasMoved = mc_move(i, e, X, Xeq, forceMatrix, E_mMinus1, E_mMinus2, L, structEq)

            # it has no sense to add the same configuration (not moved) to Ω:
            if hasMoved:
                acceptances += 1 # accepted move.
                if belongs(e, E_mMinus1, E_m): # (E[m - 1] <= e <= Em):
                    I1 += 1  # un gol más para ∫_Em-1^Em Ω(E)dE
                elif belongs(e, Eminimo, E_mMinus1): # (Emin <= e <= E[m - 1]): #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                # elif belongs(e, E_mMinus1 - 10, E_mMinus1): # (Emin <= e <= E[m - 1]):
                    I2 += 1  # un gol más para ∫_Emin^Em-1 Ω(E)dE
                #

                # randomly save some configs to use for the next subdivision:
                # if random() > ratioOfCfgsToSave: lCfgs.append([e, X])
                if random.random() > ratioOfCfgsToSave: lCfgs.append([e, X])
            #
            if (e < 1.1 * Eminimo):
                print(e, Eminimo)
                ########################################################################################
                import os
                c = counter()
                nAtoms = len(X)
                # out = "/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/ovitoPlots/moves." + str(c) + ".xyz"
                out = "ovitoPlots/moves." + str(c) + ".xyz"
                pos = str(nAtoms) + "\n\n"
                for i in range(len(X)):
                    pos += "H   " + str(X[i][0]) + "  " + str(X[i][1]) + str(X[i][2]) + "\n"
                #
                pos += "\n"

                f = open(out, "w")
                f.write(pos)
                f.close()
                ########################################################################################
                assert (1 == 0)
            # print(I1, I2, e, hasMoved, belongs(e, E_mMinus1 - 10, E_mMinus1), belongs(e, Eminimo, E_mMinus1), belongs(e,E_mMinus1, E_m), L)
        #
        ratioAcceptances = acceptances / nSteps
        print(ratioAcceptances, I2, I1, e, E_mMinus1, E_m, belongs(e, Eminimo, E_mMinus1), belongs(e,E_mMinus1, E_m), L, repeat)


        factor =  (I1 + 1) / (I2 + 1) # '+1' to avoid zeros
        assert( len(lCfgs) != 0 )

        minVal = 10
        if ( (I1 < minVal) and (I2 < minVal)):
            # choose X with lower energy
            print("A: choosing config with min energy ...")
            nthMin = 1
            e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin)
            continuar = True
        elif factor < 1/100.0:
            # choose X with higher energy
            print("B: choosing config with high energy ...")
            nthMin = 2
            e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin)
            continuar = True
        elif factor > 100:
            # choose X with lower energy
            print("C: choosing config with min energy ...")
            nthMin = 1
            e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin)
            continuar = True

        #
    #
    # # calculate α_m, log_idos:
    # alpha = I1 / I2 # MonteCarlo: ~cociente de goles ∫_Em-1^Em  / ∫_Emin^Em-1
    # assert(alpha != 0)
    # print(alpha, L)
    # log_idos.append( log_sum_idos + log(alpha) ) # =log_idos[m]
    #
    # # calculate log_sum_idos:
    # # Log of the sum of integrals for each interval, m=1, m=2, m=3,...
    # DOSintegrals = [ exp(log_int) for log_int in log_idos ]
    # log_sum_idos = log(sum(DOSintegrals))

    # output.put( (I1, I2, lCfgs) )
    # output.put( (lCfgs, alpha, log_idos, log_sum_idos, L) )
    # return lCfgs, alpha, log_idos, log_sum_idos, L
    return I1, I2, lCfgs
def randomMCmoves(Eminimo, E_mMinus1, E_m, E_mplus1,\
                  nSteps, e, X, log_idos, log_sum_idos, L):
    import copy
    import os
    # import harmonic as ha

    Eo = getEnergyConfig(X)
    Xo = copy.deepcopy(X)

    lCfgs = []  # to save cfgs for the next subdivision.
    # where: lCfgs_m = [cfg_1, cfg_2, ..., cfg_i, ...]
    # where: cfg_i = [energy_i, X_i ]
    # where: cfg_i = [energy_i, X_i ]
    # where: X_i = [r1, r2, r3, r4, ..., rNatoms]
    # where: r_n = [x,y,z]

    #===========================================================================
    # paper: "The maximum displacement of the translational moves is
    # automatically changed after each partitioning process to adjust the
    # acceptance toward the range 25%–35%. If the acceptance rate during a
    # partitioning process falls below 10% or above 70%, the partitioning
    # process is repeated."
    # L ~amplitud of random walk of a ...
    #             ...particle (dx,dy,dz) = (L*random(), L*random(), L*random())
    ratioOfCfgsToSave = 0.5
    ratioAcceptances = 0
    # L      = 0.1
    repMax = 10  #10 # maximum number of repetitions to get the appropriate ratio of
    # acceptances at a certain L value.
    repeat = 0

    ratioMin = 0.25
    ratioMax = 0.35

    while( (not belongs(ratioAcceptances, ratioMin, ratioMax) and\
            (repeat < repMax) ) or\
            continuar):

        # print(condition1, condition2, continuar, finalCondition)
        continuar = False
        # Reset energy histogram: ehist = [I1, I2].
        # I1 = c*∫_Em-1^Em Ω(E)dE;  I2 = c*∫_Emin^Em-1 Ω(E)dE, `c` is some constant.

        if (repeat > 0):
            # if I2 == 0:
            #     repeat = 0
            #     # L = 0.99 * L
            if ratioAcceptances > ratioMax:
                L = 1.1 * L
                print("...... increasing L = ", float("{0:.3f}".format(L)),
                      repeat, ratioAcceptances)
                X = copy.deepcopy(Xo)
                return 0
            elif ratioAcceptances < ratioMin:
                L = 0.9 * L
                print("...... decreasing L = ", float("{0:.3f}".format(L)),
                      repeat, ratioAcceptances)
                X = copy.deepcopy(Xo)
                return 0
        #

        [I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty] = [0, 0, 0]
        repeat += 1
        acceptances = 0

        # L = L * 0.8 # Decrease the amplitud of the random walk to get the
        # desired ratioAcceptances range values [25%, 35%].
        # You can improve with a more sophisticated algorithm here.

        # Collect ehist for [Emin,E[m-1]] and [E[m-1],Em]:
        for i in range(nSteps):
            # get a configuration e,X after randomly move X:

            Eold = getEnergyConfig(X)
            # assert( Eo == getEnergyConfig(X) )
            hasMoved = False
            Xtemp = copy.deepcopy(X)
            Xtemp = getNewConfig(i, Xtemp, L)
            Enew = getEnergyConfig(Xtemp)
            # P_old2new = getProbTransition(E_new, E_old, E_m, E_m_minus_1)
            # P_old2new = getProbTransition(Enew, Eold, E_mplus1, E_m)

            os.system("echo " + str(Enew) + " >> out2.txt")

            # if (Enew <= E_mplus1 + 0.001):
            if (Enew <= E_mplus1 + 0.0006):
                # if ( P_old2new >= random() ):
                os.system("echo " + str(Enew) + " >> out.txt")
                hasMoved = True
                e = Enew
                X = copy.deepcopy(Xtemp)
            #
            # hasMoved = True
            # e = Enew
            # X = copy.deepcopy(Xtemp)

            # e, X, hasMoved = mc_move(i, e, X, E_mplus1, E_m, E_mMinus1, L)

            # # Xo = copy.deepcopy(X)
            # # assert(id(Xo) != id(X))
            # # e, Xtemporal, hasMoved = mc_move(i, e, Xo, Xeq, forceMatrix, E_mMinus1, E_mMinus2, L, a1, a2, a3)
            #
            # # assert(id(Xo) != id(Xtemporal))
            # # if (hasMoved == False):
            # #     for k in range(len(Xo)):
            # #         for l in range(3) :
            # #             assert(Xo[k][l] == Xtemporal[k][l])
            # #         #
            # # X = copy.deepcopy(Xtemporal)
            #
            #
            # c = counter()
            # rHyper, deltaEharmonic = ha.getHarmonicEnergy(X, Xeq, forceMatrix)
            # out = "/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/ovitoPlots/rHyperEHarmonic" + str(c) + ".txt"
            # # s = str(rHyper) + " , " + str(deltaEharmonic) + " , " +  str(E_new) + "\n"
            # s = str(rHyper) + " , " + str(deltaEharmonic) + "\n"
            # f = open(out, "w")
            # f.write(s)
            # f.close()

            # it has no sense to add the same configuration (not moved) to Ω:
            if hasMoved:
                acceptances += 1  # accepted move.
                if belongs(
                        e, Eminimo, E_m
                ):  # (Emin <= e <= E[m - 1]): #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                    I_EminToEm += 1  # un gol más para ∫_Emin^Em-1 Ω(E)dE
                elif belongs(e, E_m, E_mplus1):  # (E[m - 1] <= e <= Em):
                    I_EmToEmplus1 += 1  # un gol más para ∫_Em-1^Em Ω(E)dE
                elif E_mplus1 < e:
                    I_Emplus1ToInfty += 1
                #

                # randomly save some configs to use for the next subdivision:
                if random() > ratioOfCfgsToSave: lCfgs.append([e, X])
            #
            if (e < 1.1 * Eminimo):
                print(e, Eminimo)
                ########################################################################################
                import os
                c = counter()
                nAtoms = len(X)
                out = "/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/ovitoPlots/moves." + str(
                    c) + ".xyz"
                pos = str(nAtoms) + "\n\n"
                for i in range(len(X)):
                    pos += "H   " + str(X[i][0]) + "  " + str(X[i][1]) + str(
                        X[i][2]) + "\n"
                #
                pos += "\n"

                f = open(out, "w")
                f.write(pos)
                f.close()
                ########################################################################################
                assert (1 == 0)
            # print(I1, I2, e, hasMoved, belongs(e, E_mMinus1 - 10, E_mMinus1), belongs(e, Eminimo, E_mMinus1), belongs(e,E_mMinus1, E_m), L)
        #
        ratioAcceptances = acceptances / nSteps
        # print(ratioAcceptances, I_EminToEm, I_EmToEmplus1, e, E_m, E_mplus1, belongs(e, Eminimo, E_m), belongs(e,E_m, E_mplus1), L, repeat)
        # print(ratioAcceptances, I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty, L, repeat)
        f = (I_EminToEm + I_EmToEmplus1) / (I_EminToEm + I_EmToEmplus1 +
                                            I_Emplus1ToInfty)
        ff = I_EmToEmplus1 / (I_EmToEmplus1 + I_Emplus1ToInfty)
        print(float("{0:.3f}".format(ratioAcceptances)),
              I_EminToEm, I_EmToEmplus1, I_Emplus1ToInfty, "...",
              float("{0:.3f}".format(f)), float("{0:.3f}".format(ff)), L,
              repeat, Eo)

        factor = (I_EmToEmplus1 + 1) / (I_EminToEm + 1)  # '+1' to avoid zeros
        assert (len(lCfgs) != 0)
        # if ( (I_EmToEmplus1 < 100) or (I_EminToEm < 100)):
        #     # choose X with lower energy
        #     print("A: choosing config with min energy ...")
        #     nthMin = 1
        #     e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin)
        #     continuar = True
        if factor < 1 / 100.0:
            # # choose X with higher energy
            print("B: choosing config with high energy ...")
            # nthMin = 2
            # e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin)
            L = 1.1 * L
            continuar = True
        elif factor > 100:
            # choose X with lower energy
            print("C: choosing config with min energy ...")
            # nthMin = 1
            # e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin)
            L = 0.9 * L
            continuar = True

        #

        # if ( (I1 < 100) or (I2 < 100)):
        #     assert( len(lCfgs) != 0 )
        #     print("choosing config with min energy ...")
        #     nthMin = 1
        #     e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin)
        #     c = counterMin()
        #     if (c % 3 == 2):
        #         print("choosing back ...")
        #         nthMin = 3
        #         e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin)
        #     #
        #     # if (c % 5 == 4):
        #     #     print("increasing nSteps ...")
        #     #     nSteps = nSteps * 2
        #     #
        #     continuar = True

        # if (not belongs(ratioAcceptances, ratioMin, ratioMax)):
        #     assert( len(lCfgs) != 0 )
        #     # print("choosing config with max energy ...")
        #     # print("increasing L value ...")
        #     # nthMin = 2
        #     # e, Xtemp = select_start_config(lCfgs, E_mMinus1, E_m, nthMin)
        #     # X = copy.deepcopy(Xtemp)
        #
        #     nthMin = 1
        #     e, X = select_start_config(lCfgs, E_mMinus1, E_m, nthMin)
        #     continuar = True
        #
        #     if ratioAcceptances <= ratioMin:
        #         print("decreasing L value ...")
        #         L = L / 1.2
        #     elif ratioMax <= ratioAcceptances:
        #         print("increasing L value ...")
        #         L = L * 1.2
        #     # continuar = True

    #===========================================================================

    # calculate α_m, log_idos:
    alpha = I_EmToEmplus1 / I_EminToEm  # MonteCarlo: ~cociente de goles ∫_Em-1^Em  / ∫_Emin^Em-1
    assert (alpha != 0)
    print("....................................alpha = " +
          str(float("{0:.3f}".format(alpha))) + "   L = " +
          str(float("{0:.3f}".format(L))))
    log_idos.append(log_sum_idos + log(alpha))  # =log_idos[m]

    # calculate log_sum_idos:
    # Log of the sum of integrals for each interval, m=1, m=2, m=3,...
    DOSintegrals = [exp(log_int) for log_int in log_idos]
    log_sum_idos = log(sum(DOSintegrals))

    return lCfgs, alpha, log_idos, log_sum_idos, L