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
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
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