2015-05-10 16 views
6

Sử dụng phiên bản gần đây của sympy (0.7.6) tôi nhận được kết quả xấu sau khi xác định không thể thiếu của một hàm với sự hỗ trợ [0, y):Integral chức năng piecewise cho kết quả không chính xác

from sympy import * 
a,b,c,x,z = symbols("a,b,c,x,z",real = True) 
y = Symbol("y",real=True,positive=True) 
inner = Piecewise((0,(x>=y)|(x<0)|(b>c)),(a,True)) 
I = Integral(inner,(x,0,z)) 
Eq(I,I.doit()) 

http://mathurl.com/l8wrjcn.png

Điều này không chính xác vì kết quả thực tế sẽ có hai trường hợp cuối cùng được hoán đổi. Điều này có thể được khẳng định bằng cách kiểm tra đạo hàm:

Derivative(I.doit(),z).doit().simplify().subs(z,x) 

http://mathurl.com/mg4zpts.png

làm giảm đến 0 ở khắp mọi nơi.

Điều thú vị là, khi thả các điều kiện (b>c) bằng cách thay inner = Piecewise((0,(x>=y)|(x<0)),(a,True)) tôi nhận được một Lỗi Loại:

TypeError: cannot determine truth value of 
-oo < y 

Tôi có sử dụng thư viện không đúng cách hoặc là, đây là một lỗi nghiêm trọng sympy?

Trả lời

4

Có, sympy 0.7.6 là sai trong trường hợp này và trong một số trường hợp như vậy. Nói chung, tôi không biết bất kỳ gói toán học biểu tượng nào mà tôi sẽ tin cậy để thực hiện phép tính với các hàm được xác định theo từng phần.

Lưu ý rằng mặc dù

inner = Piecewise((0, (x>=y)|(x<0)), (a,True)) 

ném một TypeError lúc hội nhập, một định nghĩa một cách logic tương đương

inner = Piecewise((a, (x<y)&(x>=0)), (0,True)) 

dẫn đến kết quả chính xác

Piecewise((a*z, And(z < y, z >= 0)), (0, And(z <= 0, z >= -oo)), (a*y, True)) 

Bằng cách này, trước đó phiên bản, sympy 0.7.5, xử lý

inner = Piecewise((0, (x>=y)|(x<0)), (a,True)) 

mà không có một TypeError, tạo ra kết quả chính xác (trong một hình thức khác nhau):

Piecewise((0, z <= 0), (a*y, z >= y), (a*z, True)) 

Dưới đây là một, ví dụ đơn giản về hành vi buggy:

>>> Integral(Piecewise((1,(x<1)|(z<x)), (0,True)) ,(x,0,2)).doit() 
-Max(0, Min(2, Max(0, z))) + 3 

>>> Integral(Piecewise((1,(x<1)|(x>z)), (0,True)) ,(x,0,2)).doit() 
-Max(0, Min(2, Max(1, z))) + 3 

Đầu tiên kết quả là không đúng (ví dụ: không thành công cho z = 0). Thứ hai là chính xác. Sự khác biệt duy nhất giữa hai công thức là z<x so với x>z.

+0

Cảm ơn, điều đó xác nhận sự nghi ngờ của tôi. Bất kỳ cái nhìn sâu sắc nào về lý do tại sao các gói toán học mang tính biểu tượng đấu tranh rất nhiều với các chức năng định nghĩa từng phần? Tôi tin rằng nó chỉ là vấn đề chia tách tích phân và chọn giới hạn tích hợp đúng. Không nên sympy nâng cao một NotImplementedError trên các chức năng piecewise nếu điều này được biết là hành vi buggy? – Lars

+0

Tôi không biết sympy internals. Tôi chỉ biết thực nghiệm rằng cuộc đấu tranh CAS với những thứ như vậy, ví dụ [Wolfram Alpha] (http://www.wolframalpha.com/input/?i=integral+abs%28sin%28x%29%29) nhận được tích phân vô hạn của | sin x | sai rồi. Nếu bạn có quyền truy cập vào Maple hoặc Mathematica (tôi không có mặt), bạn có thể muốn so sánh kết quả với chúng. –

+0

Trên thực tế, kết quả tôi nhận được từ ma trận alpha là dấu (c) (sin (x)) + c, chính xác là antiderivative (lưu ý rằng trong trường hợp xác định c phải tăng 2 cho mỗi nửa giai đoạn). – Lars

Các vấn đề liên quan