是否可以优化一个变量依赖于另一个变量的曲线拟合?

问题描述 投票:0回答:1

我想知道是否可以将 od 曲线拟合为双指数,其中参数 b 严格优于参数 d? 我不明白如何添加这样的约束。

这是一个最小的例子

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

x = np.linspace(0,4,50) # Example data

def func(x, a, b, c, d):
    return a * np.exp(b * x) + c * np.exp(d * x)

y = func(x, 2.5, 1.3, 0.5, 0.5) # Example exponential data

# Here you give the initial parameters for a,b,c which Python then iterates over
# to find the best fit
popt, pcov = curve_fit(func,x,y,p0=(1.0,1.0,1.0,1.0))
python optimization scipy curve-fitting
1个回答
0
投票

一般情况下可以吗?是的 -

curve_fit
可以吗?没有。

如果你的目标函数不是假的,那么你还需要边界并且应该适合对数尺度;我不显示这一点。

此外,严格优越使其听起来像是大于,这在数值优化中通常是不可能的。使用更大的等于,如果这是一个问题,添加一些小的 epsilon。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize, LinearConstraint


def func(x: np.ndarray, a: float, b: float, c: float, d: float) -> np.ndarray:
    return a*np.exp(b*x) + c*np.exp(d*x)


def least_squares(abcd: np.ndarray, x: np.ndarray, y: np.ndarray)-> float:
    y_actual = func(x, *abcd)
    error = y - y_actual
    return error.dot(error)


def main() -> None:
    # Example data
    rand = np.random.default_rng(seed=0)
    x = np.linspace(0,4,50)
    y = func(x, 2.5, 1.3, 0.5, 0.5) * rand.uniform(low=0.9, high=1.1, size=x.size)

    p0 = 2.4, 1.2, 0.4, 0.6

    result = minimize(
        fun=least_squares, x0=p0, args=(x, y),
        # b >= d
        constraints=LinearConstraint(
            A=(0, 1, 0, -1),
            lb=0,
        ),
    )
    
    # assert result.success, result.message
    # would fail due to lack of bounds, poor initial guess, and failure to fit on the log scale
    
    print(result.x)

    fig, ax = plt.subplots()
    ax.semilogy(x, y, label='experiment')
    ax.semilogy(x, func(x, *p0), label='estimate')
    ax.semilogy(x, func(x, *result.x), label='fit')
    ax.legend()
    plt.show()


if __name__ == '__main__':
    main()

© www.soinside.com 2019 - 2024. All rights reserved.