maxima之自定义函数库

据说maxima是个能够代替maple或mathematica的开源数学软件,使用过后发现解决一般的问题还可以,如果要解决专业一点的问题,恐怕就需要自己来编写函数库了,由于资料严重缺乏,只能做一步看一步。

第一步:让maxima找到自定义函数库

编写自己的函数库之前,首先做的事就是让maxima能够找到你写的函数库,这需要修改变量file_search_maxima,这是个list类型的变量,所以要用append函数来添加新的路径。在终端里打开maxima,输入命令file_search_maxima; 系统输出:

(%o1) [/home/zy/.maxima/###.{mac,mc},
/usr/local/share/maxima/5.20.1/share/###.{mac,mc}, /usr/local/share/maxima/5.2/
0.1/share/{affine,algebra,algebra/charsets,algebra/solver,calculus,colnew,coln/
ew/lisp,combinatorics,contrib,contrib/altsimp,contrib/amatrix,contrib/bitwise,/
contrib/boolsimp,contrib/descriptive,contrib/diffequations,contrib/diffequatio/
ns/tests,contrib/distrib,contrib/ezunits,contrib/finance,contrib/format,contri/
b/fourier_elim,contrib/fractals,contrib/fresnel,contrib/gentran,contrib/gentra/
n/man,contrib/gentran/test,contrib/gf,contrib/graphs,contrib/Grobner,contrib/i/
ntegration,contrib/levin,contrib/lurkmathml,contrib/maximaMathML,contrib/mccli/
m,contrib/namespaces,contrib/noninteractive,contrib/nset,contrib/numericalio,c/
ontrib/pdiff,contrib/prim,contrib/rand,contrib/sarag,contrib/simplex,contrib/s/
implex/Tests,contrib/solve_rec,contrib/state,contrib/stats,contrib/stringproc,/
contrib/unit,contrib/vector3d,contrib/Zeilberger,diffequations,diff_form,draw,/
dynamics,hypergeometric,integequations,integration,lapack,lapack/blas,lapack/l/
apack,lbfgs,linearalgebra,lisp-utils,macro,matrix,minpack,minpack/lisp,misc,my/
lib,numeric,orthopoly,physics,simplification,sym,tensor,trigonometry,utils,vec/
tor}/###.{mac,mc}]

 

猜测###为通配符,试着输入file_search_maxima:append(file_search_maxima,["/home/zy/maxima/###.{mac,mc}"]); 这个意思是把/home/zy/maxima作为新的函数库路径加入,系统输出:

(%o2) [/home/zy/.maxima/###.{mac,mc},
/usr/local/share/maxima/5.20.1/share/###.{mac,mc}, /usr/local/share/maxima/5.2/
0.1/share/{affine,algebra,algebra/charsets,algebra/solver,calculus,colnew,coln/
ew/lisp,combinatorics,contrib,contrib/altsimp,contrib/amatrix,contrib/bitwise,/
contrib/boolsimp,contrib/descriptive,contrib/diffequations,contrib/diffequatio/
ns/tests,contrib/distrib,contrib/ezunits,contrib/finance,contrib/format,contri/
b/fourier_elim,contrib/fractals,contrib/fresnel,contrib/gentran,contrib/gentra/
n/man,contrib/gentran/test,contrib/gf,contrib/graphs,contrib/Grobner,contrib/i/
ntegration,contrib/levin,contrib/lurkmathml,contrib/maximaMathML,contrib/mccli/
m,contrib/namespaces,contrib/noninteractive,contrib/nset,contrib/numericalio,c/
ontrib/pdiff,contrib/prim,contrib/rand,contrib/sarag,contrib/simplex,contrib/s/
implex/Tests,contrib/solve_rec,contrib/state,contrib/stats,contrib/stringproc,/
contrib/unit,contrib/vector3d,contrib/Zeilberger,diffequations,diff_form,draw,/
dynamics,hypergeometric,integequations,integration,lapack,lapack/blas,lapack/l/
apack,lbfgs,linearalgebra,lisp-utils,macro,matrix,minpack,minpack/lisp,misc,my/
lib,numeric,orthopoly,physics,simplification,sym,tensor,trigonometry,utils,vec/
tor}/###.{mac,mc}, /home/zy/maxima/###.{mac,mc}]

果然新的函数库路径被加入了。

但是这个路径没有被保存,如果重启maxima,则file_search_maxima变量恢复原样,为了让系统能够保存,可以在~/.maxima/maxima-init.mac里加入上面的append命令,maxima启动的时候就会自动执行,从而修改file_search_maxima变量。

在终端下输入cd ~/,进入我的帐号主文件夹,发现没有.maxima文件夹,这没关系,自己创建一个就行了。

终端下输入mkdir .maxima,创建了.maxima目录,进去后用emacs创建maxima-init.mac文件,写入file_search_maxima:append(file_search_maxima,["/home/zy/maxima/###.{mac,mc}"]); 保存后启动maxima,发现新的函数库路径被加入。

试着在/home/zy/maxima下创建文件a.mac,并在maxima命令提示符下输入load(a); 系统输出

(%o2)                        /home/zy/maxima/a.mac

说明系统根据新的函数库路径找到了新创建的函数库a.mac

第二步:创建函数库

按照我的理解,当用load命令载入函数库的时候,maxima就像执行脚本一样从头到尾把mac文件里所有的语句都执行了一遍,如果语句可以立即执行,比如赋值语句,那么就当场执行,如果是定义函数,那就解释了放在内存里准备随时调用。所以,函数库真没什么特别的,只要写函数的定义就行了。

在maxima里,定义函数的语法是

fun(x1,x2,...,xn):=(exp1,exp2,...,expm);

其中fun是函数名,x1,x2,...,xn是参数名,exp1,exp2,....,expm是函数体中的m个语句,expm的值作为函数的返回值。

如果返回的语句写在中间,则要用以下形式:

fun(x1,x2,....,xn):=block([a:a0,b,c:c0],exp1,exp2,...,if a>0 then return(exps),...,expm);

注意其中return(exps)不可少,block后的[a:a0,b,c:c0]是局部变量,而且可以用a:a0的方式来赋初值。

要注意的还有maxima的语法和lisp类似,也是函数型语言,所以这个定义中的expx可以看作参数,中间用的是逗号而不是分号,expm尾不需要加逗号,定义末尾也可以用$来代替分号。

最后给个例子来说明一下,这个函数从拉格朗日函数得到拉格郎日方程

 

/*equation: 把拉格朗日函数转换成拉格朗日方程*/
/*其中position velocity都是表*/
/*以下为辅助函数*/
/*getequ: 用递归的方法来生成拉格朗日方程*/
getequ(lagrange,pos,vel):=
block([equlist:[],p,v],
    if not(pos=[] and vel=[]) then
    (
        p:first(pos),
        v:first(vel),
        equlist:[diff(diff(lagrange,v),t)=diff(lagrange,p)],
        equlist:append(equlist,getequ(lagrange,rest(pos),rest(vel)))
       
    ),
    return(equlist)
)$
   
equation(lagrange,position,velocity):=
block(
    if listp(position) and listp(velocity) then
    (
       
        if (length(position)=length(velocity)) then
           (
            return(getequ(lagrange,position,velocity))
           )
        else
           (
            print("the length of position must equal to velocity")
           )
    )
    else
    (
        print("position and velocity must be list")
    )
)$

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Python中求函数的极值,可以使用不同的方法,其中一种常用的方法是使用牛顿法。牛顿法是一种迭代方法,通过计算函数的导数和二阶导数,来逐步逼近极值点。以下是一个使用牛顿法求解多元函数极值的示例代码: ```python import scipy.signal as sg import numpy as np def get_maxima(values: np.ndarray): """找到极大值点""" max_index = sg.argrelmax(values)[0] return max_index, values[max_index] def get_minima(values: np.ndarray): """找到极小值点""" min_index = sg.argrelmin(values)[0] return min_index, values[min_index] if __name__ == '__main__': data = np.array([2, 1.5, 1, 1.5, 2, 3, 2, 0, 2, 3, 0]) print("极值点下标", "极值") print(get_minima(data)) print(get_maxima(data)) ``` 这个示例代码使用了Scipy中的`argrelmax`和`argrelmin`函数来找到函数数据中的极大值和极小值点。你可以将你的函数数据作为输入,并调用相应的函数来获得极值点的下标和值。 另外,如果你想要可视化多元函数的极值点,你可以使用Matplotlib。以下是一个示例代码,其中使用了Matplotlib中的3D绘图功能来绘制函数曲面和极值点: ```python import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np def Fun(x, y): return x - y**2 - 2*x**2 - 2*x*y def PxFun(x, y): return 1 - 4*x - 2*y def PyFun(x, y): return -1 - 2*x - 2*y fig = plt.figure() ax = Axes3D(fig) X, Y = np.mgrid[-2:2:40j, -2:2:40j] Z = Fun(X, Y) ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap="rainbow") ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') step = 0.0008 x = 0 y = 0 tag_x = [x] tag_y = [y] tag_z = [Fun(x, y)] new_x = x new_y = y Over = False while Over == False: new_x -= step * PxFun(x, y) new_y -= step * PyFun(x, y) if Fun(x, y) - Fun(new_x, new_y) < 7e-9: Over = True x = new_x y = new_y tag_x.append(x) tag_y.append(y) tag_z.append(Fun(x, y)) ax.plot(tag_x, tag_y, tag_z, 'r.') plt.title('(x,y)~(' + str(x) + "," + str(y) + ')') plt.show() ``` 这个示例代码中定义了一个多元函数`Fun`,以及其对x和y的偏导数函数`PxFun`和`PyFun`。然后使用取样点的坐标和函数值创建了一个3D图像,并使用梯度下降方法找到了该函数的极值点。最后,使用红色的点将极值点在图像中标出。 希望这些示例代码对你有所帮助,可以让你在Python中求解函数的极值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值