def getbSeqPlanUltra (xstart:list, xend:list, N:int, btrue:list, binit:list, c, Ve, jacf, funcf, initplan=None, NSIG=10, smallestdetVb=1e-6, implicit=False, lognorm=False, dotlim=100, verbose=False):
    """
    Осуществляет последовательное планирование и оценку коэффициентов модели
    :param xstart: начало диапазона x
    :param xend: конец диапазона x
    :param N: количество точек в плане эксперимента
    :param binit: стартовое значение вектора коэффициентов
    :param btrue: истинное значение вектора коэффициентов
    :param c: словарь дополнительных переменных
    :param Ve:  ковариационная матрица y
    :param jacf: функция, возвращающая якобиан модели, входящие x,b,c,y
    :param funcf: функция, возвращающая значение модели, входящие x,b,c
    :param initplan: - начальный план
    :param NSIG:
    :param implicit - неявность функции. Если функция неявна, то в gknu sign=0
    :param lognorm - требуется ли использование логнорм для получения измеренных данных
    :return: k, число итераций, лог
    Для переделывания на реальные измерения btrue=None и функции моделирования переводятся на измерительные
    """
    startplan = initplan if initplan else o_p.makeRandomUniformExpPlan(xstart, xend, N)
    origplan = copy.copy(startplan)
    measdata = o_p.makeMeasAccToPlan_lognorm(funcf, startplan, btrue, c, Ve) if lognorm else o_p.makeMeasAccToPlan(funcf, startplan, btrue, c, Ve)
    log=""
    b=binit
    prevdetVb=None
    for numiter in range(dotlim): #ограничитель цикла - если выход произошёл по ограничению, значит, возможна ошибка

        estim=o_e.grandCountGN_UltraX1(funcf, jacf, measdata, b, c, NSIG, implicit=implicit, verbose=False) #получили оценку b binit=b
        #measdata почему-то разная, причины неизвестны.
        b=estim[0]
        Sk=estim[1]
        Vb=o_p.countVbForMeasdata(b,  c, Ve, jacf, measdata)
        #посчитали определитель
        detVb=np.linalg.det(Vb)

        if verbose:
            print ("Sequence Plan Iteration: {0}\nb={1}\ndetVb={2}\nprevdetVb={3} \nSk={4}".format(numiter, b, detVb, prevdetVb, Sk))

        condition=prevdetVb!=None and math.fabs(detVb-prevdetVb)/prevdetVb<math.pow(10,-1) #если вышли на плато
        prevdetVb=detVb

        if condition:
            return b, numiter, Sk, startplan, origplan, log, estim, measdata, detVb #то всё вернуть

        #иначе поиск следующей точки плана

        xdot=copy.copy(xstart) #получили начальную точку начальное значение - ровно пополам диапазона
        for i in range(len(xstart)): #присвоили ей значение
            xdot[i]=xstart[i]+(xend[i]-xstart[i])/2

        #объектная функция
        measure=lambda x,b,c:o_p.makeMeasOneDot_lognorm(funcf, x, b, c, Ve) if lognorm else o_p.makeMeasOneDot(funcf, xdot, b, c, Ve)

        function = lambda x: np.linalg.det(o_p.countVbForPlan(o_g.appendToList(startplan, x),b,c,Ve,jacf, measure))
        #funcf заменено на measure, которая добавляет дисперсию.

        #function и measure есть разные функции - первая даёт идеальный результат, вторая - с дисперсией
        #создать функцию, которая будет возвращать полученные от func данные, налагая дисперсию.
        #каждый раз будет пытаться добавить в план точку и вернуть определитель с добавленной точкой
        #где тут добавлять дисперсию, а где - не добавлять, есть тащем-та вопрос открытый

        xdot=o_g.doublesearch (xstart, xend, xdot, function) #оптимизировали значение точки

        startplan.append(xdot)
        #measdata.append({'x':xdot, 'y':funcf(xdot,b,c)})

        ymeas=o_p.makeMeasOneDot_lognorm(funcf, xdot, btrue, c, Ve) if lognorm else o_p.makeMeasOneDot(funcf, xdot, btrue, c, Ve)
        measdata.append({'x':xdot, 'y':ymeas})
        #measdata = o_p.makeMeasAccToPlan_lognorm(funcf, startplan, btrue, c, Ve) if lognorm else o_p.makeMeasAccToPlan(funcf, startplan, btrue, c, Ve)




    #окончание этого цикла "естественным путём" говорит о том, что превышено максимальное число итераций
    return b, dotlim, Sk, startplan, origplan, log+"ERROR: maximum number of iterations archieved", estim, measdata, detVb
Пример #2
0
def getbSeqPlanUltra(xstart: list,
                     xend: list,
                     N: int,
                     btrue: list,
                     binit: list,
                     c,
                     Ve,
                     jacf,
                     funcf,
                     initplan=None,
                     NSIG=10,
                     smallestdetVb=1e-6,
                     implicit=False,
                     lognorm=False,
                     dotlim=500,
                     verbose=False,
                     terminationOptDict={}):
    """
    Осуществляет последовательное планирование и оценку коэффициентов модели
    :param xstart: начало диапазона x
    :param xend: конец диапазона x
    :param N: количество точек в плане эксперимента
    :param binit: стартовое значение вектора коэффициентов
    :param btrue: истинное значение вектора коэффициентов
    :param c: словарь дополнительных переменных
    :param Ve:  ковариационная матрица y
    :param jacf: функция, возвращающая якобиан модели, входящие x,b,c,y
    :param funcf: функция, возвращающая значение модели, входящие x,b,c
    :param initplan: - начальный план
    :param NSIG:
    :param implicit - неявность функции. Если функция неявна, то в gknu sign=0
    :param lognorm - требуется ли использование логнорм для получения измеренных данных
    :param dotlim - предел добавленных точек
    :param verbose - выводить ли информацию по итерациям
    :param terminationOptDict - словарь опций завершения итеративного процесса:
        VdShelfPow - по умолчанию -1 math.fabs(detVb-prevdetVb)/prevdetVb<math.pow(10,-VdShelfPow) NSIG для полки по detVb

    :return: k, число итераций, лог
    Для переделывания на реальные измерения btrue=None и функции моделирования переводятся на измерительные // btrue вообще должен бы быть исключен из всех функций ofiura
    """

    startplan = initplan if initplan else o_p.makeRandomUniformExpPlan(
        xstart, xend, N)
    origplan = copy.copy(startplan)
    measdata = o_p.makeMeasAccToPlan_lognorm(
        funcf, startplan, btrue, c, Ve) if lognorm else o_p.makeMeasAccToPlan(
            funcf, startplan, btrue, c, Ve)
    log = ""
    b = binit
    prevdetVb = None
    for numiter in range(
            dotlim
    ):  #ограничитель цикла - если выход произошёл по ограничению, значит, возможна ошибка
        estim = o_e.grandCountGN_UltraX1(
            funcf,
            jacf,
            measdata,
            b,
            c,
            NSIG,
            implicit=implicit,
            verbose=False)  #получили оценку b binit=b
        #measdata почему-то разная, причины неизвестны.
        b = estim[0]
        Sk = estim[1]
        Vb = o_p.countVbForMeasdata(b, c, Ve, jacf, measdata)
        #посчитали определитель
        detVb = np.linalg.det(Vb)

        if verbose:
            print(
                "Sequence Plan Iteration: {0}\nb={1}\ndetVb={2}\nprevdetVb={3} \nSk={4}"
                .format(numiter, b, detVb, prevdetVb, Sk))

        VdShelfPow = terminationOptDict[
            'VdShelfPow'] if 'VdShelfPow' in terminationOptDict else -1

        condition = prevdetVb != None and math.fabs(
            detVb - prevdetVb) / prevdetVb < math.pow(
                10, VdShelfPow)  #если вышли на плато

        prevdetVb = detVb

        if condition:
            return b, numiter, Sk, startplan, origplan, log, estim, measdata, detVb  #то всё вернуть

        #иначе поиск следующей точки плана

        xdot = copy.copy(
            xstart
        )  #получили начальную точку начальное значение - ровно пополам диапазона
        for i in range(len(xstart)):  #присвоили ей значение
            xdot[i] = xstart[i] + (xend[i] - xstart[i]) / 2

        #объектная функция
        measure = lambda x, b, c: o_p.makeMeasOneDot_lognorm(
            funcf, x, b, c, Ve) if lognorm else o_p.makeMeasOneDot(
                funcf, xdot, b, c, Ve)

        function = lambda x: np.linalg.det(
            o_p.countVbForPlan(o_g.appendToList(startplan, x), b, c, Ve, jacf,
                               measure))
        #function = lambda x: np.linalg.det(o_p.countVbForPlan(o_g.appendToList(startplan, x),b,c,Ve,jacf, funcf))
        #funcf заменено на measure, которая добавляет дисперсию.

        #function и measure есть разные функции - первая даёт идеальный результат, вторая - с дисперсией
        #создать функцию, которая будет возвращать полученные от func данные, налагая дисперсию.
        #каждый раз будет пытаться добавить в план точку и вернуть определитель с добавленной точкой
        #где тут добавлять дисперсию, а где - не добавлять, есть тащем-та вопрос открытый

        xdot = o_g.doublesearch(xstart, xend, xdot,
                                function)  #оптимизировали значение точки

        startplan.append(xdot)
        #measdata.append({'x':xdot, 'y':funcf(xdot,b,c)})

        ymeas = o_p.makeMeasOneDot_lognorm(
            funcf, xdot, btrue, c, Ve) if lognorm else o_p.makeMeasOneDot(
                funcf, xdot, btrue, c, Ve)

        #примитивная защита от кривых результатов измерения
        if ymeas != None:
            measdata.append({'x': xdot, 'y': ymeas})

        #measdata = o_p.makeMeasAccToPlan_lognorm(funcf, startplan, btrue, c, Ve) if lognorm else o_p.makeMeasAccToPlan(funcf, startplan, btrue, c, Ve)

    #окончание этого цикла "естественным путём" говорит о том, что превышено максимальное число итераций
    return b, dotlim, Sk, startplan, origplan, log + "ERROR: maximum number of iterations archieved", estim, measdata, detVb
Пример #3
0
def grandApriornPlanning (xstart:list, xend:list, N:int, bstart:list, bend:list, c, Ve, jac, func=None, Ntries=30, verbosePlan=False, initplan=None, verbose=False):
    """
    Реализует априорное планирование эксперимента
    :param xstart: начало диапазона x (вектор)
    :param xend: конец диапазона x  (вектор)
    :param N: размер плана (количество контрольных точек)
    :param bstart: начало диапазона b (вектор)
    :param bend: конец диапазона b (вектор)
    :param c: словарь дополнительных переменных
    :param Ve: Ковариационная матрица y, реально её диагональ (вектор)
    :param jac: Якобиан функции, принимает на вход x,b,c,y
    :param verbosePlan: если true, пишет все планы в файлы, иначе только оптимальный
    :param initplan: начальный план. По умолчанию случаен, но может быть задан (в этом случае делается одна попытка)
    :param verbose: выдавать ли в консоль информацию optimized-original
    :return: кортеж: 0: оптимизированное значение определителя Vb, 1: оптимальный план эксперимента
    """

#Апдейт: теперь по умолчанию в список планов заряжается равномерный

    dopt=100000000
    planopt=None

    Ntries1=Ntries+1
    if initplan!=None:
        Ntries1=1


    if verbose:
        print('\n\nДанные априорного планирования:')
        print('Неоптимизированное-оптимизированное значение среднего det(Vb)')

    prevtime=time.time()

    for i in range(0,Ntries1):
        try:


            if initplan==None:
                m=len(xstart) #длина вектора входных параметров
                plan = o_p.makeUniformExpPlan(xstart, xend, N**(1/float(m))) if i==0 else o_p.makeRandomUniformExpPlan(xstart, xend, N)

                if verbose:
                    print('plan length:', len(plan))

            else:
                plan = initplan
            unopt=countMeanVbForAprior_S4000(plan, bstart, bend, c, Ve, jac, func)[0]
            #оптимизация
            for j in range(N):
                xdot=copy.deepcopy(plan[j])
                function = lambda x: countMeanVbForAprior_S4000(o_g.replaceInList(plan,j,x), bstart, bend, c, Ve, jac, func)[0]

                boundsarr=list()
                for k in range(len(xstart)):
                    boundsarr.append((xstart[k],xend[k]))

                #sol = optimize.minimize (function, xdot, bounds=boundsarr)
                #plan[j]=sol.x
                #В этом варианте не работает, хоть результат и проходит быстрее

                plan[j]=o_g.doublesearch(xstart, xend, xdot, function)



            dcurr=countMeanVbForAprior_S4000(plan, bstart, bend, c, Ve, jac, func)[0]

            if verbose:
                curtime = time.time() #in seconds
                #st = datetime.datetime.fromtimestamp(curtime-prevtime).strftime('%Y-%m-%d %H:%M:%S')
                st = datetime.datetime.fromtimestamp(curtime-prevtime).strftime('%H:%M:%S')
                print ("{0} unoptimized-optimized: {1}   {2} time spent: {3}".format('uniform' if i==0 else '',unopt, dcurr, st))
                prevtime=copy.copy(curtime)



            if dcurr<dopt or planopt==None:
                dopt=dcurr
                planopt=plan


            if (verbosePlan):
                o_p.writePlanToFile(plan, "{0}plan.txt".format(i))






        except BaseException as e:
            print ('This try failed, due to exception e=',e)
            tb = traceback.format_exc()
            print(tb)

    return dopt, planopt