Проблема в том, что ваше первоначальное предположение очень далеко от реального решения. Если вы добавите оператор печати внутри chisqfunc()
, например print (a,b)
, и повторно запустите свой код, вы получите что-то вроде:
(0, 0)
(1.4901161193847656e-08, 0.0)
(0.0, 1.4901161193847656e-08)
Это означает, что minimize
оценивает функцию только в этих точках.
если вы теперь попытаетесь оценить chisqfunc()
на этих 3 парах значений, вы увидите, что они ТОЧНО совпадают, например
print chisqfunc((0,0))==chisqfunc((1.4901161193847656e-08,0))
True
Это происходит из-за арифметики округления с плавающей запятой. Другими словами, при вычислении stress - model
переменная stress
слишком много на порядок больше, чем model
, и результат усекается.
Затем можно было бы просто попробовать перебор, увеличив точность с плавающей запятой, записав data=data.astype(np.float128)
сразу после загрузки данных с помощью loadtxt
. minimize
не удается, с result.success=False
, но с полезным сообщением
Желаемая ошибка не обязательно достигается из-за потери точности.
Одна из возможностей состоит в том, чтобы обеспечить лучшее начальное предположение, чтобы при вычитании stress - model
часть model
имела тот же порядок величины, а другая - изменить масштаб данных, чтобы решение было ближе к вашему первоначальному предположению (0,0)
.
Будет НАМНОГО лучше, если вы просто измените масштаб данных, сделав, например, безразмерными по отношению к определенному значению напряжения (например, изгиб / растрескивание этого материала).
Это пример фитинга, в котором в качестве шкалы напряжений используется максимальное измеренное напряжение. В вашем коде очень мало изменений:
import numpy
import scipy.optimize as opt
filename = 'data.csv'
data = numpy.loadtxt(open(filename,"r"),delimiter=",")
stress = data[:,0]
strain = data[:,1]
err_stress = data[:,2]
smax = stress.max()
stress = stress/smax
#I am assuming the errors err_stress are in the same units of stress.
err_stress = err_stress/smax
def chisqfunc((a, b)):
model = a + b*strain
chisq = numpy.sum(((stress - model)/err_stress)**2)
return chisq
x0 = numpy.array([0,0])
result = opt.minimize(chisqfunc, x0)
print result
assert result.success==True
a,b=result.x*smax
plot(strain,stress*smax)
plot(strain,a+b*strain)
Ваша линейная модель довольно хороша, т.е. ваш материал имеет очень линейное поведение для этого диапазона деформации (какой это вообще материал?):
person
gg349
schedule
05.03.2014
err_stress
неопределенность измеренного напряжения для различных значений деформации? - person gg349   schedule 04.03.2014print result.x
, верно? минимизировать НЕ обновляетx0
. - person gg349   schedule 04.03.2014print result.x
. Даerr_stress
- это массив ошибок для массива измеренных напряжений. - person Will282   schedule 04.03.2014result.success
иresult.status
после звонкаminimize
? - person Warren Weckesser   schedule 05.03.2014result.success
равноTrue
,result.status
равно 0 иresult.x
равно[0 0]
. Спасибо за помощь, Уоррен. - person Will282   schedule 05.03.2014