公告:本站正式转型为非交互式静态网站!
转型:本站将通过笔记和博客的形式继续为大家服务,关于 Mathematica 问答服务请移步至QQ群:365716997
联系:如有问题请联系QQ群管理员,或发送邮件至:lixuan.xyz@qq.com。
感谢:最后非常感谢大家多年来的支持与帮助!
参考《互联网跟帖评论服务管理规定》《中华人民共和国网络安全法》《网络信息内容生态治理规定》《互联网用户账号信息管理规定》

—— 2022-11-27

欢迎来到 Mathematica 问答社区

提问时请贴上文本代码

语法高亮:在编辑器中点击

被禁止的话题:广告破解

请阅读:《提问的智慧》

备用域名:mma.ooo

支持LaTex数学公式
行内公式标识符:\$ 或“$\backslash ($”+“$\backslash )$”,
行间公式标识符:\$\$ 或 “$\backslash [$”+“$\backslash ]$”

社区建议QQ群:365716997

分类

+1 投票
6.5k 浏览

这样做不可以:
 

Map[p, Range[0, 3]] = {a, b, c, d}


而这样做却可以:


{p[0], p[1], p[2], p[3]} = {a, b, c, d}


为什么?

另:定义一个从零开始计数的数组有这么难吗?上面那个代码看来可行,但是又不想输入4次数组名。。。期待你的高见。

 
还有:math到底有没有自定义数据类型的概念?网上找了好久,好像没有。。。这么强大的功能,math为什么不支持?

分类:列表操作 | 用户: zhaozx15 (66 分)
修改于 用户:zhaozx15
楼主,无影东瓜又重新回答了你的问题,你似乎没看到哦。

3 个回答

+5 投票
 
已采纳

Evaluate[Map[p, Range[0, 3]]] = {a, b, c, d}

补充一下关于自定义数据类型的问题。严格来讲mma是没有这个功能的,但是可以做到类似的效果,比如这样

In[5]:= myList[a_List] := myListObj[a];
x_myListObj[i_] := x[[1, i + 1]];
a = myList[{1, 2, 3, 4}];
a[0]

Out[8]= 1

这几行就完成了一个基本的自定义,定义了一个叫做myList的类,通过myListObj来实现自定义数组下标。

下标的读取解决了,接下来是下标的赋值,也就是说当运行a[0]=3时需要改变a,这其实是最困难的一步。但好在stackexchange上已经有了相关讨论,直接照搬其解决方案并作小幅修改即可

(附原帖链接:http://mathematica.stackexchange.com/questions/1162/alternative-to-overloading-set)

ClearAll[withCustomSetLex];
SetAttributes[withCustomSetLex, HoldAll];
withCustomSetLex[code_] := 
Unevaluated[code] /. 
HoldPattern[Set[a_Symbol[i_], value_]] /; Head[a] == myListObj :> 
Set[a, ReplacePart[a, {1, i + 1} -> value]]

这样在withCustomSetLex中进行的赋值就可以达到目的了

接下来还希望myList支持尽可能多的运算,如加减乘除、点乘等。最开始我打算用/:把计算中需要用到的运算全部重载,后来想到其实可以直接在计算中把myListObj化为List处理,因为myListObj和List只有在[]运算符和Set时才有区别,其他时候完全一样,因此只需在withCustomSetLex最后加上一句myListObj->Identity即可。

为了方便计算,将withCustomSetLex放入$Pre,这样就可以正常的操作myListObj了。

附完整代码与例子如下:

(*定义部分*)
ClearAll[myList, myListObj];
myList[a_List] := myListObj[a];
x_myListObj[i_Integer] := x[[1, i + 1]];
ClearAll[withCustomSetLex];
SetAttributes[withCustomSetLex, HoldAll];
withCustomSetLex[code_] := 
Unevaluated[code] /. 
HoldPattern[Set[a_Symbol[i_], value_]] /; Head[a] == myListObj :>
(Set[a, ReplacePart[a, {1, i + 1} -> value]]; value) /. 
myListObj -> Identity;
$Pre = withCustomSetLex;

然后进行一些测试

可见大部分运算都可以进行

但也有一些会失败的例子,如Length、Total、{3,4,5,6}/b等等,用的时候还是需要多加小心

用户: 无影东瓜 (1.2k 分)
采纳于 用户:amita
谢谢,的确可用。我还尝试了其它的实现方式,目前想到两种:

FVSet[p_, lis_] :=
  MapThread[Set, {Table[p[mu], {mu, 0, 3}], lis}];
或者
FVSet[p_, lis_] := Do[p[mu] = lis[[mu + 1]], {mu, 0, 3}];
谢谢。让兄台费心了。我有点觉得越是高级、越是高度定制的编程语言,局限越大,但是好处是很多方面使用方便。mma我用的最多的就是用它化简公式,的确强大。编程技巧也很初级,所以我水平的确比论坛上各位差太多,但是也基本够用了。

再次感谢!
+3 投票
一看就知道兄台是从其它基础编程语言转过来的,很多编程习惯要改改。

p[],方括号内是参数列表,这可不是数组操作啊!

p[[]],这才是数组操作。
另外,没有必要定义从0开始的数组,如果有需要加个1就行了。
比如k:0,1,2,...,n,使用时加个1,p[[k+1]]

 

在Mma中,变量是不需要定义数据类型的,直接赋值即可。
对于其它语言中的“结构体”,在Mma中灵活使用List或Association或Entity即可。

用一段时间后,你会发现这样也是有好处的。
用户: 野鹤 (5.1k 分)
你好,写写你这么用心回答。[[]]是part我是知道的,正是因为math中List第0分量是它的name,也就是List,所以才尝试使用函数f[x_]。

C和Fortran都学过,用后者更多些,发现它很标准易用,数组从零开始计数,只要array(0:3)即可。之所以纠缠数组从零计数,原因是自己的专业,粒子物理中随处可见的四矢量。物理约定四个分量是0,1,2,3。当然在math里面定义数组从1计数也没有问题,但是操作起来总是不够直接了当。比如定义能量动量四矢量p={E,p1,p2,p3}; 按照math,p[[1]]=E,但是按照字面,我们更期望它表示的是p1。话说Wolfram也是理论物理的博士。。。哦哦,扯远了。哈哈。
看了你和东瓜的回答,还是建议你习惯使用从1开始的数组索引。
另外,Mathematica一般简称为Mma。
@zhaozx15 涉及 QFT 你确定你不用 FeynCalc ?
FeynCalcl一般只是在计算trace和缩并的时候才用,平时化简公式大都是自己写一些简单的mma code。
+1 投票

第一个问题,Map[p, Range[0, 3]] = {a, b, c, d}为什么不可以,是因为:

赋值的=,其函数名是Set,Set具有HoldFirst属性,那么HoldFirst属性的意义,可以参考下面这个链接里我的回答。

http://mmaqa.com/index.php/1050/%E8%87%AA%E5%8F%98%E9%87%8F%E8%A2%ABholdfirst%E6%88%96holdall%E5%90%8E

怎么解决,就像无影东瓜所说,加个Evaluate.

第二个问题,mma没有数组这个概念,只有列表这个概念。

第三个问题,什么是“自定义数据类型”?如果是指c里的structure,那么直接写就是了。

p={{"小明",12,"xiaomin"},{"小红",13,"xiaohong"},{"小刘",14,"xiaoliu"}};

p是一个人物信息表,包含三个人物信息,其中p[[1]]是小明的信息,p[[1,3]]是小明的英文名字。

当然也可以用Association实现,当表的数据量有些大的时候那就很有必要用Association了。

从上一个例子也能看出,你的代码没啥必要用p[1]到p[4]。直接p={1,2,3,4}不就行了。然后想用哪个分量就用Part提取。想获得长度就Length。

用户: 苹果 (2.2k 分)
修改于 用户:苹果
我期望我的代码所见即所指。

定义两个四矢量缩并:标准定义是: a.b = a0*b0 - a1*b1 - a2*b2 - a3*b3。在mma里面定义代码如下:dot[a_,b_]:=a[[1]] b[[1]]-a[[2]] b[[2]]-a[[3]] b[[3]]-a[[4]] b[[4]]。实在别扭。

还有取第一分量p[[1]]也就是理工科学生都学过的动量p_x,但是按照p={E,p1,p2,p3}这个定义,p[[1]]其实是E,能量。别扭。
如果你不同意我说的话,大可以举例反驳,而不是一句干巴巴的毫无意义的话.就像假如我用“我还真学过”来回你,也是毫无意义,所以我写了这么长一段话.
dot还可以这样定义的:
dot[{x1_,x2_,x3_,x4_},{y1_,y2_,y3_,y4_}]:=x1 y1-x2 y2-x3 y3-x4 y4
确实别扭。但是为何不定义一个 metric matrix ?
...