Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中分配变量值之前对变量执行操作_Python_Variables_Bezier_Polynomials - Fatal编程技术网

在Python中分配变量值之前对变量执行操作

在Python中分配变量值之前对变量执行操作,python,variables,bezier,polynomials,Python,Variables,Bezier,Polynomials,好的,所以基本上我的问题是将思维方式从解决“纸上”的数学问题转变为通过编程来解决。让我解释一下:我想知道在给变量赋值之前,是否可以对变量执行操作。比如,如果我有类似于(1-x)的东西**n我可以先给n分配一个值,然后从特定的角度将其转换为a,然后给x一个或多个值。如果我不够清楚:如果n=2,我可以先将方程转换为形式1-2x+x**2,然后在下一步处理x值吗 我想写一个计算和绘制n次贝塞尔曲线的代码。我使用伯恩斯坦多项式,所以我意识到方程由三部分组成:第一部分是多项式系数,它们都是帕斯卡三角形的一

好的,所以基本上我的问题是将思维方式从解决“纸上”的数学问题转变为通过编程来解决。让我解释一下:我想知道在给变量赋值之前,是否可以对变量执行操作。比如,如果我有类似于
(1-x)的东西**n
我可以先给n分配一个值,然后从特定的角度将其转换为a,然后给x一个或多个值。如果我不够清楚:如果n=2,我可以先将方程转换为形式
1-2x+x**2
,然后在下一步处理x值吗

我想写一个计算和绘制n次贝塞尔曲线的代码。我使用伯恩斯坦多项式,所以我意识到方程由三部分组成:第一部分是多项式系数,它们都是帕斯卡三角形的一部分;我正在计算它们并将它们放在一个列表中。第二部分是控制点的坐标这也是一些系数,并将它们放在单独的列表中。现在是最难的部分:方程中有变量的部分。伯恩斯坦使用的是气压中心坐标(表示u和1-u)。方程这部分的N次公式是:

u**i  *(1-u)**(n-i)
其中,n是曲线度数,我从0->n开始,U是变量。U是实际标准化的变量,这意味着它的值可以从0到1,我希望稍后在一定数量的步骤(如1000)中对其进行计数但问题是,如果我尝试使用上面提到的方程,我会不断出错,因为Python不知道如何处理u。我教过嵌套循环,其中第一个循环将u的值从0到1,第二个循环将处理上面提到的从0到n的方程,但不确定它是否是正确的解决方案,也不知道如何检查结果。什么你认为呢?
PS:我没有上传代码,因为我遇到问题的那部分我甚至无法启动,而且,我认为这可能是错误的,它与代码的其余部分是分开的;但是如果你认为它可以帮助解决问题,我可以上传它。

有一些用于进行符号数学的Python软件包,但是使用一些可用的软件可能更容易一些Numpy中的ble。这些函数使用多项式表示为系数数组的约定,从最低阶系数开始。因此多项式
a*x^2+b*x+c
将表示为
数组([c,b,a])

一些例子:

In [49]: import numpy.polynomial.polynomial as poly

In [50]: p = [-1, 1]  # -x + 1

In [51]: p = poly.polypow(p, 2)

In [52]: p # should be 1 - 2x + x^2
Out[52]: array([ 1., -2.,  1.])

In [53]: x = np.arange(10)

In [54]: poly.polyval(x, p)  # evaluate polynomial at points x
Out[54]: array([  1.,   0.,   1.,   4.,   9.,  16.,  25.,  36.,  49.,  64.])
你可以用类似的方法计算伯恩斯坦多项式(仍然缺少一个二项式系数):


有Python软件包可以进行符号数学运算,但是使用Numpy中的一些可用函数可能更容易。这些函数使用的约定是,多项式表示为系数数组,从最低阶系数开始。因此,多项式
a*x^2+b*x+c
将表示为
数组([c,b,a])

一些例子:

In [49]: import numpy.polynomial.polynomial as poly

In [50]: p = [-1, 1]  # -x + 1

In [51]: p = poly.polypow(p, 2)

In [52]: p # should be 1 - 2x + x^2
Out[52]: array([ 1., -2.,  1.])

In [53]: x = np.arange(10)

In [54]: poly.polyval(x, p)  # evaluate polynomial at points x
Out[54]: array([  1.,   0.,   1.,   4.,   9.,  16.,  25.,  36.,  49.,  64.])
你可以用类似的方法计算伯恩斯坦多项式(仍然缺少一个二项式系数):


您可以使用高阶函数,即返回函数的函数,如

def Bernstein(n,i):
    def f(t):
        return t**i*(1.0-t)**(n-i)
    return f
你可以这样用

b52 = Bernstein(5,2)
val = b52(0.74)
linear = mk_bezier([0.0,1.0],[1.0,0.0])
quadra = mk_bezier([0.0,1.0,2.0],[1.0,3.0,1.0])

for t in (0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0):
    l = linear(t) ;  q = quadra(t)
    print "%3.1f     (%6.4f,%6.4f)    (%6.4f,%6.4f)" % (t,  l[0],l[1],  q[0],q[1])
但是,您更愿意使用列表

Bernstein_ni = [Bernstein(n,i) for i in range(n+1)]
在高阶函数中用于构建贝塞尔曲线函数

def mk_bezier(Px,Py):
    "Input, lists of control points, output a function of t that returns (x,y)" 
    n = len(Px)
    binomials = {0:[1], 1:[1,1], 2:[1,2,1],
                 3:[1,3,3,1], 4:[1,4,6,4,1], 5:[1,5,10,10,5,1]}
    binomial = binomials[n-1]
    bPx = [b*x for b,x in zip(binomial,Px)]
    bPy = [b*y for b,y in zip(binomial,Py)]
    bns = [Bernstein(n-1,i) for i in range(n)]
    def f(t):
        x = 0 ; y = 0
        for i in range(n):
            berns = bns[i](t)
            x = x + bPx[i]*berns
            y = y + bPy[i]*berns
        return x, y
    return f
最终,在您的程序中,您可以像这样使用函数工厂

b52 = Bernstein(5,2)
val = b52(0.74)
linear = mk_bezier([0.0,1.0],[1.0,0.0])
quadra = mk_bezier([0.0,1.0,2.0],[1.0,3.0,1.0])

for t in (0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0):
    l = linear(t) ;  q = quadra(t)
    print "%3.1f     (%6.4f,%6.4f)    (%6.4f,%6.4f)" % (t,  l[0],l[1],  q[0],q[1])
这是测试输出

0.0     (0.0000,1.0000)    (0.0000,1.0000)
0.1     (0.1000,0.9000)    (0.2000,1.3600)
0.2     (0.2000,0.8000)    (0.4000,1.6400)
0.3     (0.3000,0.7000)    (0.6000,1.8400)
0.4     (0.4000,0.6000)    (0.8000,1.9600)
0.5     (0.5000,0.5000)    (1.0000,2.0000)
0.6     (0.6000,0.4000)    (1.2000,1.9600)
0.7     (0.7000,0.3000)    (1.4000,1.8400)
0.8     (0.8000,0.2000)    (1.6000,1.6400)
0.9     (0.9000,0.1000)    (1.8000,1.3600)
1.0     (1.0000,0.0000)    (2.0000,1.0000)
编辑 我认为正确的方法是在模块级,使用一种顶级的-
defaultdictionary
,它记录执行实际计算所需的所有不同列表,但是
defaultdict
不会将变量传递给它的
default\u工厂,我也不想将
dict
子类化(不是现在)为了这个答案,主要原因是我以前从来没有子类化过

回应OP的评论 你说函数度是主要参数?但它是由控制点列表的长度隐式定义的

N   = user_input()
P0x = user_input()
P0y = user_input()
PNx = user_input()
PNy = user_input()
# code that computes P1, ..., PNminus1
orderN = mk_bezier([P0x,P1x,...,PNminus1x,PNx],
                   [P0y,P1y,...,PNminus1y,PNy])

x077, y077 = orderN(0.77)

但是客户总是对的,因此如果您声明我的解决方案与您的期望不同,我将不再试图说服您我的解决方案适合您。

您可以使用高阶函数,即返回函数的函数,如

def Bernstein(n,i):
    def f(t):
        return t**i*(1.0-t)**(n-i)
    return f
你可以这样用

b52 = Bernstein(5,2)
val = b52(0.74)
linear = mk_bezier([0.0,1.0],[1.0,0.0])
quadra = mk_bezier([0.0,1.0,2.0],[1.0,3.0,1.0])

for t in (0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0):
    l = linear(t) ;  q = quadra(t)
    print "%3.1f     (%6.4f,%6.4f)    (%6.4f,%6.4f)" % (t,  l[0],l[1],  q[0],q[1])
但是,您更愿意使用列表

Bernstein_ni = [Bernstein(n,i) for i in range(n+1)]
在高阶函数中用于构建贝塞尔曲线函数

def mk_bezier(Px,Py):
    "Input, lists of control points, output a function of t that returns (x,y)" 
    n = len(Px)
    binomials = {0:[1], 1:[1,1], 2:[1,2,1],
                 3:[1,3,3,1], 4:[1,4,6,4,1], 5:[1,5,10,10,5,1]}
    binomial = binomials[n-1]
    bPx = [b*x for b,x in zip(binomial,Px)]
    bPy = [b*y for b,y in zip(binomial,Py)]
    bns = [Bernstein(n-1,i) for i in range(n)]
    def f(t):
        x = 0 ; y = 0
        for i in range(n):
            berns = bns[i](t)
            x = x + bPx[i]*berns
            y = y + bPy[i]*berns
        return x, y
    return f
最终,在您的程序中,您可以像这样使用函数工厂

b52 = Bernstein(5,2)
val = b52(0.74)
linear = mk_bezier([0.0,1.0],[1.0,0.0])
quadra = mk_bezier([0.0,1.0,2.0],[1.0,3.0,1.0])

for t in (0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0):
    l = linear(t) ;  q = quadra(t)
    print "%3.1f     (%6.4f,%6.4f)    (%6.4f,%6.4f)" % (t,  l[0],l[1],  q[0],q[1])
这是测试输出

0.0     (0.0000,1.0000)    (0.0000,1.0000)
0.1     (0.1000,0.9000)    (0.2000,1.3600)
0.2     (0.2000,0.8000)    (0.4000,1.6400)
0.3     (0.3000,0.7000)    (0.6000,1.8400)
0.4     (0.4000,0.6000)    (0.8000,1.9600)
0.5     (0.5000,0.5000)    (1.0000,2.0000)
0.6     (0.6000,0.4000)    (1.2000,1.9600)
0.7     (0.7000,0.3000)    (1.4000,1.8400)
0.8     (0.8000,0.2000)    (1.6000,1.6400)
0.9     (0.9000,0.1000)    (1.8000,1.3600)
1.0     (1.0000,0.0000)    (2.0000,1.0000)
编辑 我认为正确的方法是在模块级,使用一种顶级的-
defaultdictionary
,它记录执行实际计算所需的所有不同列表,但是
defaultdict
不会将变量传递给它的
default\u工厂,我也不想将
dict
子类化(不是现在)为了这个答案,主要原因是我以前从来没有子类化过

回应OP的评论 你说函数度是主要参数?但它是由控制点列表的长度隐式定义的

N   = user_input()
P0x = user_input()
P0y = user_input()
PNx = user_input()
PNy = user_input()
# code that computes P1, ..., PNminus1
orderN = mk_bezier([P0x,P1x,...,PNminus1x,PNx],
                   [P0y,P1y,...,PNminus1y,PNy])

x077, y077 = orderN(0.77)

但是客户总是对的,所以如果您声明我的解决方案与您的期望不同,我将不再试图说服您我的解决方案对您有效。

可能要求类似的东西?@hagubear不确定它是否能解决问题,但肯定会测试它……谢谢您想要做的是保持表达n保存在变量中,为表达式中使用的变量赋值,然后解析表达式,使其使用值并返回结果?@pythonstarter在我看来,您似乎想定义一个变量的函数,
def(u):…;返回计算值
但我很难认为你与这个概念无关…@g