网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
10月15日漏签0天
mathematica吧 关注:20,006贴子:74,352
  • 看贴

  • 图片

  • 吧主推荐

  • 游戏

  • 5回复贴,共1页
<<返回mathematica吧
>0< 加载中...

MMA内置函数重造

  • 只看楼主
  • 收藏

  • 回复
  • situxuming
  • 小吧主
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
最近在看Power Programming with Mathematica: The kernel,因为这本书里面的MMA版本较老,所以现在版本里的很多函数,再那里都还没有,因为后面的练习题有一些是函数重造的练习题。编写了一点,感觉MMA内置函数重造也是一个不错的熟悉、练习MMA编程的过程,尽管有的时候自己编写的函数相比内置函数,运行效率差距不是一点点。函数重造的一个要求就是要能实现内置函数的全部功能,后面抛砖引玉编写了两个:
1. 首先是Extract,Extract有两个功能,
一个就是取出元素Extract[expr,{list1,list2,...}]
另一个是在取出元素之后,在其计算之前加上函数头h,即Extract[expr,list,h]
重造函数及其功能实现如下图:

2,第二个是NumericQ的重造
最简单的办法就是NumberQ[N[expr]]
另外还有一个递归的算法,思想就是数字或者MMA常数比如Pi则是数字量,或者函数头具有NumericFunction属性且其所有参数都是数字或MMA常数,则是数字量。算法如下:
myNumericQ1[x_, appendx___] :=
If[AtomQ[x], True,
MemberQ[Attributes[Evaluate@Head[x]], NumericFunction]] &&
If[AtomQ[x], NumberQ[x] || MemberQ[Attributes[x], Constant],
myNumericQ[Sequence @@ x]] &&
If[{appendx} === {}, True, myNumericQ[Sequence @@ appendx]]
递归算法就是有一个不足,有递归限制,然后运行效率 不是很高
另外一个改进算法,就是提取出表达式的所有函数头以及参数,Union去除重复的,然后分别检测函数头跟参数是否满足上述条件,对于Atom,则单独处理:
myNumericQ[expr_?AtomQ] :=
NumberQ[expr] || MemberQ[Attributes[expr], Constant]
myNumericQ[expr_] :=
With[{all =
Union[Select[Level[expr, Infinity, Heads -> True], AtomQ]],
leaf = Union[Select[Level[expr, Infinity], AtomQ]]},
And @@ Flatten@{(NumberQ[#] || MemberQ[Attributes[#], Constant]) & /@
leaf, MemberQ[Attributes[#], NumericFunction] & /@
Complement[all, leaf]}]
这些就随便玩玩,欢迎交流,有兴趣的朋友也可以贴上自己重构的函数,对于这两个函数,有改进的算法也欢迎交流

运行情况来看,myNumericQ还可以,这么一个复杂的式子也可以检测出来,但是myNumericQ1递归的定义方式就有点问题了,t这么一个复杂的表达式就无法判断了,对于简单的式子还可以,问题出在哪里,有空了再检查检查,而至于NumberQ[N[expr]]的重造方式,只要计算不超过$MaxNumber,都是可行的,这也是NumberQ[N[expr]]的弱点,要判断,必须先计算


  • mm_酱
  • 刚刚会用
    10
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
NestList:
ClearAll[myNestList];
myNestList[f_, expr_, n_] := Module[{val = expr},
Reap[
Do[
Sow[val = f[val]], {n}]
][[2, 1]]
]


2026-10-15 07:22:33
广告
不感兴趣
开通SVIP免广告
  • mm_酱
  • 刚刚会用
    10
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
性能测试:
内置的最快;
Reap和Sow也不错;
Linked List凑合;
AppendTo悲剧(注意测试的次数只有1000次,上面几个都是10000次)。


  • 草红样
  • 小吧主
    9
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
函数式语言中的几乎所有函数都能用递归定义,一般都很简洁,不过mma中的递归效率不高:
Clear["`*"];
range[start_: 1, end_, step_: 1] := If[(end - start)*step < 0, {},
{start}~Join~range[start + step, end, step]]
map[f_, {}] = {};
map[f_, {x_, xs___}] := {f@x}~Join~map[f, {xs}];
select[{}, f_] = {};
select[{x_, xs___}, f_] :=
If[f@x, {x}~Join~select[{xs}, f], select[{xs}, f]]
fold[f_, init_, {}] = init;
fold[f_, init_, {x_, xs___}] := fold[f, f[init, x], {xs}]
foldList[f_, init_, {}] = {init};
foldList[f_, init_, {x_, xs___}] :=
{init}~Join~foldList[f, f[init, x], {xs}];
nest[f_, init_, 0] = init;
nest[f_, init_, n_] := nest[f, f[init], n - 1];
nestList[f_, init_, 0] = {init};
nestList[f_, init_, n_] := {init}~Join~nestList[f, f[init], n - 1];
flatten[e_] = {e};
flatten[ls_List] := Join @@ flatten /@ ls
range[5]
range[1, 5]
range[1, 9, 2]
range[10, 0, -2]
map[#^2 &, {1, 3, 5}]
select[range@10, EvenQ]
fold[Times, 1, range@10]
foldList[Times, 1, range@10]
nest[2 # &, 1, 10]
nestList[2 # &, 1, 10]
flatten@fold[List, 0, range@10]


  • 草红样
  • 小吧主
    9
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
tuples[L_, 0] := {{}};
tuples[L_, k_] := Join @@ Table[{x}~Join~y, {x, L}, {y, tuples[L, k - 1]}];
tuples[{1, 2, 3}, 2]


  • 草红样
  • 小吧主
    9
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
reverse[ls_] := Fold[{#2}~Join~# &, {}, ls];
select[ls_, f_] := Fold[If[f@#2, #~Join~{#2}, #] &, {}, ls];
reverse@Range@10
select[Range@10, EvenQ]


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 5回复贴,共1页
<<返回mathematica吧
分享到:
©2026 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示