Tùy thuộc vào nhu cầu cụ thể của bạn , có thể hữu ích khi cắt đối số đầu vào thành exp()
. Nếu bạn thực sự muốn có được inf
nếu nó tràn hoặc bạn muốn nhận được số lượng khổng lồ vô lý, thì các câu trả lời khác sẽ thích hợp hơn.
def powellBadlyScaled(X):
f1 = 10**4 * X[0] * X[1] - 1
f2 = numpy.exp(-numpy.float(X[0])) + numpy.exp(-numpy.float(X[1])) - 1.0001
return f1 + f2
def powellBadlyScaled2(X):
f1 = 10**4 * X[0] * X[1] - 1
arg1 = -numpy.float(X[0])
arg2 = -numpy.float(X[1])
too_big = log(sys.float_info.max/1000.0) # The 1000.0 puts a margin in to avoid overflow later
too_small = log(sys.float_info.min * 1000.0)
arg1 = max([min([arg1, too_big]), too_small])
arg2 = max([min([arg2, too_big]), too_small])
# print(' too_small = {}, too_big = {}'.format(too_small, too_big)) # Uncomment if you're curious
f2 = numpy.exp(arg1) + numpy.exp(arg2) - 1.0001
return f1 + f2
print('\nTest against overflow: ------------')
x = [-1e5, 0]
print('powellBadlyScaled({}) = {}'.format(x, powellBadlyScaled(x)))
print('powellBadlyScaled2({}) = {}'.format(x, powellBadlyScaled2(x)))
print('\nTest against underflow: ------------')
x = [0, 1e20]
print('powellBadlyScaled({}) = {}'.format(x, powellBadlyScaled(x)))
print('powellBadlyScaled2({}) = {}'.format(x, powellBadlyScaled2(x)))
Kết quả:
Test against overflow: ------------
*** overflow encountered in exp
powellBadlyScaled([-100000.0, 0]) = inf
powellBadlyScaled2([-100000.0, 0]) = 1.79769313486e+305
Test against underflow: ------------
*** underflow encountered in exp
powellBadlyScaled([0, 1e+20]) = -1.0001
powellBadlyScaled2([0, 1e+20]) = -1.0001
ý rằng powellBadlyScaled2
không qua/underflow khi bản gốc powellBadlyScaled
đã làm, nhưng phiên bản sửa đổi cho 1.79769313486e+305
thay vì inf
thuộc một trong các bài kiểm tra. Tôi tưởng tượng có rất nhiều ứng dụng trong đó 1.79769313486e+305
thực tế là inf
và điều này sẽ ổn, hoặc thậm chí được ưa thích bởi vì 1.79769313486e+305
là một số thực và inf
thì không.
Nguồn
2018-01-12 05:24:40
Bạn cần điều chỉnh thuật toán của mình. Nếu giá trị không vừa, nó không vừa. Tìm một cách khác để diễn tả phép tính không tràn. –
Điều duy nhất hợp lý bạn có thể làm là nhìn vào hành vi tiệm cận của chức năng của bạn. Nếu đó là hợp lý, sau đó trên một số ngưỡng bạn có thể thay thế tính toán rõ ràng bằng giá trị tiệm cận. Nếu giá trị tiệm cận không hợp lý thì vấn đề rất có thể là do bạn chọn thuật toán, chứ không phải trong mã. – DaveP
DaveP, hành vi tiệm cận của exp là exp ... –