首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >大数目的羔羊

大数目的羔羊
EN

Stack Overflow用户
提问于 2022-02-23 07:37:55
回答 2查看 38关注 0票数 0

我有(由SymPy自动生成的)表达式,包括在sqrt下面有大数字的sqrt函数和前面的小乘法器。因此,总体结果必须在浮动范围内,但sqrt -下的值不是。我使用lambdify命令将这个表达式转换为Python函数。调用此函数将获得异常:

代码语言:javascript
运行
复制
from sympy import *
t = symbols("t")
k = 10
f = 2 * 10 ** (- k) * sqrt(10 ** (2 * k) * t ** 2 + 1)
print(f)
F = lambdify(t, f)
t0 = 10 ** 10
T = np.arange(t0, 2 * t0, t0 / 4)
print(T)
F(T)

输出:

代码语言:javascript
运行
复制
2.0e-10*sqrt(100000000000000000000*t**2 + 1)
[1.00e+10 1.25e+10 1.50e+10 1.75e+10]
AttributeError: 'float' object has no attribute 'sqrt'

The above exception was the direct cause of the following exception:

TypeError                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_15740/1035914544.py in <module>
      8 T = np.arange(t0, 2 * t0, t0 / 4)
      9 print(T)
---> 10 F(T)

<lambdifygenerated-11> in _lambdifygenerated(t)
      1 def _lambdifygenerated(t):
----> 2     return 2.0e-10*sqrt(100000000000000000000*t**2 + 1)

TypeError: loop of ufunc does not support argument 0 of type float which has no callable sqrt method

对于k = 2代码,可以正常工作:

代码语言:javascript
运行
复制
0.02*sqrt(10000*t**2 + 1)
[1.00e+10 1.25e+10 1.50e+10 1.75e+10]
array([2.0e+10, 2.5e+10, 3.0e+10, 3.5e+10])

有任何方法可以不手动重写表达式来修复这个问题吗?

UPD:看起来这是NumPy的一个问题:

代码语言:javascript
运行
复制
import numpy as np
k = 10
def F1(t):
    return np.sqrt( (10 ** (- k)) ** 2 * 10 ** (2 * k) * t ** 2 + 1)
def F2(t):
    return 10 ** (- k) * np.sqrt(10 ** (2 * k) * t ** 2 + 1)
print(F1(10 ** 5))
print(F2(10 ** 5))

第一次呼叫有效,第二次呼叫-不!

EN

回答 2

Stack Overflow用户

发布于 2022-02-23 08:26:48

将np.sqrt的参数转换为numpy.double解决了以下问题:

代码语言:javascript
运行
复制
def Sqrt(x):
  return np.sqrt(np.double(x))
F = lambdify(t, f, {'sqrt': Sqrt})
票数 1
EN

Stack Overflow用户

发布于 2022-02-23 08:33:44

由于乘法器很大,所以np.sqrt参数是对象dtype数组:

代码语言:javascript
运行
复制
In [3]: 100000000000000000000 * T**2
Out[3]: array([1e+40, 1.5625e+40, 2.25e+40, 3.0625e+40], dtype=object)

对于对象dtype数组,numpy迭代(以列表理解的速度),对每个元素应用“方法”。有效

代码语言:javascript
运行
复制
 1e+40.sqrt() etc

因此出现了no method error

你的解决办法:

代码语言:javascript
运行
复制
In [3]: np.double(100000000000000000000 * T**2)
Out[3]: array([1.0000e+40, 1.5625e+40, 2.2500e+40, 3.0625e+40])

In [4]: np.sqrt(_)
Out[4]: array([1.00e+20, 1.25e+20, 1.50e+20, 1.75e+20])

代码语言:javascript
运行
复制
In [6]: np.sqrt((100000000000000000000 * T**2).astype(float))
Out[6]: array([1.00e+20, 1.25e+20, 1.50e+20, 1.75e+20])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71232932

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档