无法对三角函数的值进行采样

时间:2019-04-27 14:11:39

标签: python

我的代码有问题。 所以我尝试代表函数'sin(t ^ 3)/ 2 ^ tan(t)'的采样值 t在0到1.5之间,频率fs = 50Hz。

我创建了一个函数“ sampleFunction”,该函数将代表三角函数,间隔开始,间隔结束和频率的字符串作为参数。 我创建了tVector(0,0.02,0.04,..,1.48) 然后我取tVector的元素,并用它们评估字符串并将结果放入另一个向量y 我同时返回y和tVector

但是我在运行它时遇到一个问题,说“ y”未定义 这是代码:

import numpy as np
import matplotlib.pyplot as plt
import math

def sampleFunction(functionString,t0,t1,fs):
      tVector=np.arange(start=t0, stop=t1, step=1/fs, dtype='float')
      t=t0
      for i in range(0,len(tVector)):
         t=tVector[i]
         y[i]=eval(functionString)
      return y,tVector

 t0=0
 t1 =1.5
 fs=50
 thold=.1
 functionString='math.sin(t**3)/2**math.tan(t)'
 y,t=sampleFunction(functionString,t0,t1,fs)
 plt.plot(t,y)
 plt.xlabel('time')
 plt.ylabel('Amplitude')

3 个答案:

答案 0 :(得分:1)

您可以通过以下方式更改代码:

def sampleFunction(functionString,t0,t1,fs):
      tVector=np.arange(start=t0, stop=t1, step=1/fs, dtype='float')
      t=t0
      y = np.zeros( tVector.shape )
      for i in range(0,len(tVector)):
         t=tVector[i]
         y[i]=eval(functionString)
      return y,tVector

但是,这不是一个好的python。有几个问题:

  1. 您应该使用向量化操作。
  2. 您应该避免eval那样的瘟疫。这具有安全隐患。

对于矢量化操作,只需执行以下操作:

def sampleFunction(functionString,t0,t1,fs):
      t = np.arange(start=t0, stop=t1, step=1/fs, dtype='float')
      y = eval(functionString)
      return y, t

并将其称为:

sampleFunction('np.sin(t**3)/2**np.tan(t)', 0, 10, 100)

这要快得多(特别是对于大型阵列)

最后,向量化形式只有一行。您可能不需要额外的功能。

答案 1 :(得分:0)

运行上面的代码时,您应该收到一条错误消息,提示最后,“ 名称'y'未定义”。如果查看函数定义,您会发现实际上不是。您必须先定义y才能将值传递给y [i]! “ for”循环之前的以下行解决了该特定问题:

y = [None] * len(tVector)

该代码在更正后将正常运行。

但是:为什么可以传递函数时为什么要传递函数字符串?在Python中,函数是一流的对象!

答案 2 :(得分:0)

正如Harold所说的那样,您在分配'y'变量时遇到问题。

但是,有多种方法可以实现您的工作,并且eval函数是可以的,除非您有非常好的理由,否则绝对是最糟糕的。也许考虑以下可能的示例之一:

import numpy as np
import matplotlib.pyplot as plt
import math

def sampleFunction(functionString,t0,t1,fs):
      tVector=np.arange(start=t0, stop=t1, step=1/fs, dtype='float')
      t=t0
      y = [float]*len(tVector) # <------------------- Allocate 'y' variable
      for i in range(0,len(tVector)):
         t = tVector[i]
         y[i]=eval(functionString)
      return y,tVector


t0=0
t1 =1.5
fs=50
thold=.1

# Your code
functionString = 'math.sin(t**3)/2**math.tan(t)'
y, t = sampleFunction(functionString,t0,t1,fs)
plt.plot(t, y, color='cyan')

# Using the 'map' built-in function
t = np.arange(start=t0, stop=t1, step=1./fs, dtype='float')
y = map(lambda ti: 0.9*math.sin(ti**3)/2**math.tan(ti), t)
plt.plot(t, y, color='magenta')

# Using Numpy's 'sin' and 'tan'
t = np.arange(start=t0, stop=t1, step=1./fs, dtype='float')
y = 0.8*np.sin(t**3)/2**np.tan(t)
plt.plot(t, y, color='darkorange')

# Using 'list comprehensions'
t = np.arange(start=t0, stop=t1, step=1./fs, dtype='float')
y = [ 0.7*math.sin(ti**3)/2**math.tan(ti) for ti in t]
plt.plot(t, y, color='darkgreen')

plt.xlabel('time')
plt.ylabel('Amplitude')
plt.show()

结果是:

enter image description here