无法采样三角函数的值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法采样三角函数的值相关的知识,希望对你有一定的参考价值。

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

我创建了一个函数'sampleFunction',它接受表示三角函数的字符串作为参数,间隔的开始,间隔的结束和频率。我创建tVector(0,0.02,0.04,..,1.48)然后我取tVector的元素并使用它们来计算字符串并将结果放在另一个向量中我同时返回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')
答案

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

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)

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

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

另一答案

正如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

另一答案

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

y = [None] * len(tVector)

修正后代码将运行正常。

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

以上是关于无法采样三角函数的值的主要内容,如果未能解决你的问题,请参考以下文章

你能改变金属着色器中采样器的边界吗?

LWJGL 无法在着色器中采样帧缓冲纹理

为啥保守光栅化无法为某些三角形调用片段着色器?

从片段函数更改 TextView 的值

用于片段着色器的 OpenGL GLSL 绑定采样器

片段着色器中未使用纹理数据 - OpenGL