#python #python-3.x
#python #python-3.x
Вопрос:
Для моего численного курса я должен использовать правило Симпсона для аппроксимации интеграла от трех различных функций, которые перечислены ниже…. Мой код выполняется, но он не дает мне правильного приближения, и я не знаю почему….
import math
def F(x):
c = x * math.log(x)
return c
def G(x):
g = 2 / (x**2 4)
return g
def H(x):
h = x**2 * math.cos(x)
return h
def simpsonRule(f, a, b, n):
h = (b-a)/n
k = 0
z = 0
for i in range(1, (n//2) - 1):
k = 2*f(a (2*i*h))
for i in range(1, (n//2)):
z = 4*f(a ((2*i)-1)*h)
return (h*(f(a) k z f(b))) / 3
AA = simpsonRule(F, 1, 2, 4)
CC = simpsonRule(G, 0, 2, 6)
DD = simpsonRule(H, 0, math.pi, 6)
print(AA)
print(CC)
print(DD)
Комментарии:
1. используется
print()
для отображения значений в переменных в разных местах и сравнения их с вычислениями на бумаге.2. Я вижу три возможные проблемы: (1) код неверен — он неправильно использует алгоритм. (2)
math.cos()
ожидает радиус, но вы используете градусы (3) float в компьютере не может сохранять все возможные значения, поэтому он сохраняет аппроксимацию, и тогда результат не может быть идеальным. т. е.0.1 0.2 == 0.3
даетFalse
3. Можете ли вы поделиться ожидаемым результатом и для входных данных
Ответ №1:
Я считаю, что проблема в том, что верхний предел ваших range()
вызовов отключен на 1. Верхний предел никогда не достигается, поэтому он должен быть выше того, что вы хотите. Я включил дополнительный тестовый пример, sin(x)
, для которого я знал правильный ответ (~ 1):
import math
def E(x):
return math.sin(x)
def F(x):
return x * math.log(x)
def G(x):
return 2 / (x**2 4)
def H(x):
return x**2 * math.cos(x)
def simpsonRule(f, a, b, n):
h = (b - a) / n
k = 0
z = 0
for i in range(1, n // 2):
k = 2 * f(a 2 * i * h)
for i in range(1, n // 2 1):
z = 4 * f(a (2 * i - 1) * h)
return h * (f(a) k z f(b)) / 3.0
AA = simpsonRule(F, 1, 2, 4)
CC = simpsonRule(G, 0, 2, 6)
DD = simpsonRule(H, 0, math.pi, 6)
EE = simpsonRule(E, 0, math.pi / 2, 100)
print(AA)
print(CC)
print(DD)
print(EE)
ВЫВОД
> python3 test.py
0.6363098297969493
0.7853979452340107
-6.274868388453119
1.0000000003382359
>
Комментарии:
1. Результат соответствует тому, что я сделал вручную. Спасибо, но я все еще не понимаю, почему вы изменили циклы for так, как вы это сделали … если вы посмотрите на алгоритм, то ограничение от 1 до 1 / n — 1 имеет функцию, умноженную на 2, но вы умножили ее на 4 и также изменили другую… Я просто не понимаю, почему
2. @JozyMan, я не знаю, о чем ты спрашиваешь. Мой код идентичен вашему опубликованному коду, за исключением того, что верхний предел
range()
вызовов на 1 больше, и я удалил ненужные скобки. Я не вижу никаких изменений 2 против 4 или отмены.
Ответ №2:
В случае, если вы используете Python 2.x, проблема может быть вызвана типами переменных. Все переменные в правой части эксперимента h = (b-a)/n
являются int
, поэтому интерпретатор предполагает, что h
int
это также должно быть. Проблема может быть решена путем преобразования типа
a = float(a)
b = float(b)
вставлено перед этим выражением.
Упомянутое выше поведение характерно для Python 2, и оно было исправлено в Python 3, предполагая float
, что в этой ситуации. Смотрите здесь больше примеров с приведением типов в Python.
Вывод без преобразования:
0.0
0
-1.36541969235
Вывод с преобразованием:
0.208501009808
0.577327327327
-1.36541969235
Комментарии:
1.
h
было бы только int на Python 2. Спрашивающий говорит, что они на Python 3. Хотя они могут ошибаться в этом, публикация ответа, специфичного для Python 2, без предварительного изучения версии, кажется преждевременной.2. Спасибо за предложение. Я отредактировал ответ, указав, что он применим для Python 2
3. В вопросе есть два тега: один — общий вопрос python, а другой — специфичный для Python 3. Итак, я решил, что вопрос не ограничивается только Python 3.
4. Во-первых,
python
тег был отредактирован другим пользователем. Во-вторых, вопросы, относящиеся к Python 3, должны быть помечены какpython
иpython-3.x
. Предполагается, что вопросы, зависящие от версии, не должны иметьpython-3.x
тега. В-третьих, зачемpython-3.x
вообще нужен тег, если спрашивающий запускал (или считал, что он запускает) Python 2?5. Это своего рода априорное знание или где-то написано об обоих тегах? Как я должен знать, что добавлено другим пользователем? Кто-то может добавить оба тега, если он не уверен.