Почему, когда я вычитаю из своего массива, ничего не происходит? Как мне повысить точность с помощью python?

#python #python-3.x #optimization #precision

#python #python-3.x #оптимизация #точность

Вопрос:

Я не знаю, является ли моя проблема просто ошибкой в кодировании или проблемой точности.

По сути, я решаю задачу минимизации. Я пытаюсь использовать определенный алгоритм для поиска минимизатора функции. Математика, лежащая в основе того, что я делаю, на самом деле не важна, кроме того факта, что я пытаюсь вычесть [-2.65765056e-22 9.20132910e-23] из [1.2, 1, 2], и когда я это делаю, все, что я получаю обратно, это [1.2, 1.2].

Я предполагаю, что это проблема точности, поэтому я искал способ обеспечить более 64-битную точность в python, но это мне не позволит.

Я пытался преобразовать все в переменную типа float64, но это все равно не сработало. Я удалил этот код ради удобства чтения

Пожалуйста, помогите, я действительно хочу написать это на python и не опускаться до использования matlab: P (jk).

Но если серьезно, это мой код или точность, или и то, и другое? Можно ли это сделать на Python?

вот мой код:

 import numpy as np

def f(x):
    return 100*(x[0]-x[1]**2)**2 (1-x[0])**2

def df(x):
    return np.array([-400*x[0]*(x[1]-x[0]**2)*x[0]-2*(1-x[0]), 200*(x[1]-x[0]**2)])

def ndf(x):
    return x[0]**2   x[1]**2



alpha=1
row=.999
c=.5

epsilon =.0004
y=[1.2,1.2]
while ndf(df(y)) > epsilon:
   print(ndf(df(y))) 
   alpha=1 
   while f(y - alpha*df(y)) > f(y)-c*alpha*(ndf(df(y)))**2:

       alpha = row*alpha


   y=y-alpha*df(y)
   print(-alpha*df(y))
   print(y-alpha*df(y))
  

вот результаты:
Выходные данные и типы переменных

Как всегда, гуру stack over flow, спасибо!

Комментарии:

1. Вычитание вещей, которые отличаются на 23 порядка величины, является проблемой точности. Но я нахожу крайне маловероятным, что необходимость вычитать вещи, которые отличаются на 23 порядка величины, является разумной. Я бы посмотрел на алгоритм или код проблемы, а не на точность.

2. Повторно реализуйте все, используя decimal.Decimal объекты. Это допускает произвольную точность (при условии, что у вас есть память)

3. Избитый до этого. Если вы пытаетесь вычесть эту величину значений, то мне действительно интересно, что делает этот алгоритм. Это не приведет к заметному сдвигу значения в вашей жизни, если не учитывать проблемы с плавающей запятой.

4. Я почти уверен, что мой алгоритм верен. Просто изучил это снова. Это алгоритм градиентного спуска, использующий поиск по строке с обратным отслеживанием

5. Кроме того, я знаю точный ответ, это [1,1], поэтому алгоритму не нужно заходить очень далеко. Как мне использовать десятичную систему счисления. Десятичное число с массивами?

Ответ №1:

Я упрощаю проблему до точности: когда вы используете десятичную систему счисления, вы получаете хорошую точность.

 >>> import numpy as np
>>> from decimal import Decimal
>>> a = [1.2,1.2]
>>> b = [-2.65765056e-22,9.20132910e-23]
>>> a = [Decimal(i) for i in a]
>>> b = [Decimal(i) for i in b]
>>> a
[Decimal('1.1999999999999999555910790149937383830547332763671875'), Decimal('1.1999999999999999555910790149937383830547332763671875')]
>>> 
>>> 
>>> b
[Decimal('-2.657650560000000049520705664376562101548279121350202517182008919716107442354768863879144191741943359375E-22'), Decimal('9.2013290999999997555711266729024269198128893250699076740068186285037565852462648763321340084075927734375E-23')]
>>>
>>> a[0]-b[0]
Decimal('1.199999999999999955591344780')
  

Альтернативное решение: использование np.float128

 >>> a = [1.2,1.2]
>>> b = [-2.65765056e-22,9.20132910e-23]
>>>np.float(a[0]-b[0])
1.2
>>>np.float128(a[0]-b[0])
1.1999999999999999556
  

Комментарии:

1. Моим решением не были проблемы с плавающей запятой, но если бы это было так, это бы исправило это. Спасибо за ваш ответ.