Экстраполяция ошибок для длительных данных моделирования - PullRequest
0 голосов
/ 02 апреля 2020

Я использую электромагнитное c волновое моделирование структур печатных плат (печатных плат) для проектирования высокочастотной электроники. Часть этого процесса включает дискретизацию физической модели, так что уравнения Максвелла оцениваются только в определенных c точках пространства. Если я сделаю дискретизацию действительно «точной» (то есть уравнения оцениваются во многих близко расположенных точках), то симуляция будет более точной, но также займет гораздо больше времени, чем если бы я сделал дискретизацию «грубой». Время моделирования является основным фактором: грубая дискретизация занимает 5+ минут для моделирования, а очень точная - часами, днями или более. Итак, я хотел бы найти способ сделать дискретизацию настолько грубой, насколько это возможно, чтобы приблизительный результат находился в пределах некоторого заданного допуска к реальному результату.

Вот подход, который я использовал до сих пор. У меня есть какая-то функция, давайте назовем ее f(h). h представляет «тонкость» дискретизации, где дискретизация становится более точной с увеличением h. f возвращает интересующий физический результат моделирования (например, характеристики c сопротивление линии передачи). Мой подход состоял в том, чтобы оценить f при некотором начальном значении h, а затем постепенно увеличивать h. Для каждого приращения я вычисляю среднеквадратичное значение (root среднеквадратичное значение) отличие от предыдущего результата. Я использую RMS, потому что функция оценки на самом деле дает мне массив результатов для диапазона частот. Итак, если первая функция оценки дала мне массив, [a1, a2, ...], а вторая дала мне [b1, b2, ...], я бы вычислил среднеквадратичную разницу между ними как sqrt(((a1-b1)^2+(a2-b2)^2+...)/n), где n - длина каждого массива. Я продолжаю делать это для увеличивающихся приращений h, а затем вычисляю наилучшее соответствие среднеквадратичных значений на основе функции: g(h, a, b)=a/(h-b)^2, где a и b - это параметры, выбираемые при наилучшем подборе. Затем я использую это соответствие, чтобы найти сумму всех среднеквадратичных значений, которые я бы вычислил, если бы продолжил этот процесс до h->infty. Выбор этой функции несколько произвольный, но он обладает необходимыми свойствами, которые приближаются к 0, когда h приближается к бесконечности и сумма сходится. Вот фактический код (в python):

import numpy as np
from scipy.optimize import curve_fit
from scipy.special import polygamma

def optimize_parameter(func, start, step, tol, max_steps):
    """
    Compute the lowest-cost value of a parameter that still produces
    accurate results.
    """
    res1 = func(start)
    n = len(res1)
    res_matrix = np.zeros((max_steps, n), dtype=np.clongdouble)
    res_matrix[0] = np.array(res1)
    # compute the root mean square differences from the previous results array.
    rms = np.zeros((max_steps - 1,))
    i = 1
    orig_start = start
    start += step
    while i < max_steps:
        res_matrix[i] = np.array(func(start))
        diff = np.subtract(res_matrix[i], res_matrix[i - 1])
        rms[i - 1] = np.sqrt(
            np.sum(np.real(np.multiply(diff, np.conj(diff)))) / n
        )

        if i > 2:
            fit = curve_fit(rms_fit, range(orig_start, start, step), rms[:i])
            a = fit[0][0]
            b = fit[0][1]
            error_estimate = rms_remaining_sum(a, b, start + 1)

            if error_estimate < tol:
                return start

        i += 1
        start += step

    raise RuntimeError(
        "Failed to optimize parameter. Consider increasing "
        "the tolerance or max number of steps."
    )


def rms_fit(x, a, b):
    """
    """
    return np.divide(a, np.power(np.subtract(x, b), 2))


def rms_remaining_sum(a, b, c):
    """
    Computes the sum: sum(a/(x-b)^2, x=c, oo)
    """
    return a * polygamma(1, c - b)

Суммирование бесконечной серии, rms_remaining_sum можно найти с помощью wolfram alpha . Вот график RMS и соответствующего наилучшего соответствия для симуляции, которую я сейчас запускаю. Синяя линия - это действительные среднеквадратичные данные, а оранжевая линия - это соответствие.

enter image description here

соответствующие данные:

x=[6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
y=[0.1066269325,
 0.0962748651,
 0.0667883428,
 0.0461512161,
 0.0388534504,
 0.0351861963,
 0.0277184022,
 0.0200926777,
 0.0193773813,
 0.0182817032,
 0.0139113486,
 0.0137574535,
 0.0111344859,
 0.0106247568,
 0.0078254227,
 0.0077217245,
 0.0096504084]

Просто Взглянув на сюжет, подгонка выглядит довольно хорошо. Тем не менее, я не уверен, что это из-за того, что моя методология обоснована, или из-за удачи или переоснащения . Кажется ли моя стратегия разумной или вероятной ошибкой? Более того, дискретность дискретизации - не единственный параметр, который я планирую использовать с этой функцией. Действительно, любой параметр, для которого точность моделирования является (в основном) монотонно возрастающей или убывающей функцией этого параметра, является честной игрой.

Существуют ли более надежные алгоритмы для этого? Любые другие мысли?

Примечание: я намеренно пропустил информацию о электронике / симуляторе c, чтобы сосредоточиться на более общем обсуждаемом алгоритме. Если часть этой информации будет полезна (например, как выглядит дискретная печатная плата), пожалуйста, дайте мне знать, и я включу ее.

...