Я ничего не знаю о Symfit, но если вы просто пытаетесь обобщить приведенный выше код для произвольного N, то:
- Вы можете произвольно сгенерировать строку, которая выглядит как
"p1, p2, p3"
для произвольного N и разобрать его в список параметров:
params_string = ", ".join("p{}".format(i + 1) for i in range(n))
params = parameters(params_string)
Идея синтаксического анализа строки для получения списка параметров звучит для меня вонючей, и я уверен, что естьлучший способ программно объявить кучу параметров, но это будет как можно ближе к тому, что делал ваш исходный код.
РЕДАКТИРОВАТЬ: Глядя на документацию Symfit, кажется, что parameters(s)
это просто ярлык, и вы можете просто сделать:
params = [Parameter("p{}".format(i + 1)) for i in range(n)]
, который не требует, чтобы вы строили свою собственную объединенную строку из всех имен параметров, просто чтобы Symfit мог разделить их обратно на отдельные имена параметров.Это также позволит вам определить другие свойства для ваших параметров, такие как их начальные значения или их минимальные / максимальные границы.
- Вы можете обобщить ограничение
Eq
:
coeffs = [xdata[0]] + [(xdata[i+1] - xdata[i]) for i in range(n-1)]
eq_constraint = Eq(sum(param * coeff for param, coeff in zip(params, coeffs), 1)
Или, как это делает другой ответ, с использованием простых операций:
coeffs = np.concat(xdata[:1], np.diff(xdata))
eq_constraint = Eq(np.sum(params * coeffs), 1)
- Вы можете обобщить ограничения
Ge
:
ge_constraints = [Ge(params[i + 1], params[i]) for i in range(n - 1)] + [Ge(params[-1], 0]
constraints = [eq_constraint] + ge_constraints
Опять же, это можно сделать с помощью простых операций, но я оставлю это на ответ @ user3483203.
- Вы можете умножить все параметры, используя
reduce
:
model = reduce(lambda x, y: x * y, params, 1)
Или используя numpy.prod
:
model = np.prod(params)
Это должно бытьдостаточно обобщить сказанное выше до произвольной N.