I tried to fit a sin-function by finding the parameter, which has lowest error-value.
Below is my code:
import numpy as np
import scipy.optimize as opt
from scipy.optimize import leastsq
import matplotlib.pyplot as plt
def func_model(x, para):
''' Model: y = a*sin(2*k*pi*x+theta)'''
a, k, theta = para
return a*np.sin(2*k*np.pi*x+theta)
def func_noise(x, para):
a, k, theta = para
return a*np.sin(2*k*np.pi*x+theta) + np.random.randn(100)
def func_error(para_guess):
'''error_func'''
error_sum = 0
x_seq = np.linspace(-2*np.pi, 0, 100)
para_fact = [10, 0.34, np.pi/6]
for x in x_seq:
error_value = (func_noise(x, para_fact)-func_model(x, para_guess))**2
error_sum = error_sum + error_value
return error_sum
para_guess_init = np.array([7, 0.2, 0])
solution = opt.fmin(func_error, para_guess_init)
print(solution)
But it doesn't work, and said the error: setting an array with a sequence
Traceback:
File "", line 26, in <module>
solution = opt.fmin(func_error, para_guess_init)
File "C:\Users\sun\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\optimize.py", line 408, in fmin
res = _minimize_neldermead(func, x0, args, callback=callback, **opts)
File "C:\Users\sun\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\optimize.py", line 532, in _minimize_neldermead
fsim[k] = func(sim[k])
ValueError: setting an array element with a sequence.
Can someone help me, thanks in advance
This minimizer expects a scalar function-evaluation to minimize.
Your function func_error
returns a vector of size (100,)
.
Compare your line:
error_value = (func_noise(x, para_fact)-func_model(x, para_guess))**2
with for example:
error_value = np.sum(np.square(
func_noise(x, para_fact)-func_model(x, para_guess)))
although i would prefer (objective changes!):
error_value = np.linalg.norm(
func_noise(x, para_fact)-func_model(x, para_guess))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.