Module Mathematica模块不返回值

Module Mathematica模块不返回值,module,wolfram-mathematica,mathematical-optimization,Module,Wolfram Mathematica,Mathematical Optimization,我是Mathematica新手,使用模块执行一个过程,然后返回一个值。然而,Mathematica似乎在计算并返回符号值,而不是我想要的数值 我的问题是:你什么时候不用分号?什么时候用Return[value]而不是写“value” DumpVar[x_]:=Print[ToString[HoldForm[x],“:”,x]; SetAttributes[DumpVar,{Listable,HoldAll}] 宽度=1; 间隔=宽度/2; 面板系数=2; 光照角度=π/3; (*面板和灯光方程*

我是Mathematica新手,使用模块执行一个过程,然后返回一个值。然而,Mathematica似乎在计算并返回符号值,而不是我想要的数值

我的问题是:你什么时候不用分号?什么时候用Return[value]而不是写“value”

DumpVar[x_]:=Print[ToString[HoldForm[x],“:”,x];
SetAttributes[DumpVar,{Listable,HoldAll}]
宽度=1;
间隔=宽度/2;
面板系数=2;
光照角度=π/3;
(*面板和灯光方程*)
面板[x_]=Abs[panelCoeff x];(*panelCoeff((x)^2);*)
光[x_u3;]=Tan[光角度]*x;
getAngleAttack[偏移量]:=
模块[{bounce1x,l1a,lightSlope,panelSlope},
灯光[x_u3;]=灯光'[x](x-偏移)+面板[间隔];
DumpVar[offset];
lightSlope=N[light'[offset]];
u1S=光'[偏移];
u1[x_1;]=(u1S(x-偏移))+面板[间隔];
反弹1x=
x/.N[NSolve[u1[x]==面板[x]&x-interval,
x] ];
u1r[x_1;]=面板'[bounce1x](x-bounce1x)+面板[bounce1x];
如果[Length[bounce1x]>0,
bounce1x=bounce1x[[1]];,
反弹1x=偏移量;
]
如果[bounce1x>-间隔&&bounce1x如果[x在你的街区中间,你有:

If[Length[bounce1x] > 0,
  bounce1x = bounce1x[[1]];,
  bounce1x = offset;
  ]
If
的格式如下:
If[Condition,ValueIfTrue,ValueIfFalse]

因此,
If[True,3,2]
返回3,而
If[False,3,2]
返回2。此处不需要分号,但在If语句末尾需要分号:

If[Length[bounce1x] > 0,
  bounce1x = bounce1x[[1]],
  bounce1x = offset
  ];
否则,Mathematica会将其解释为该语句乘以下一个出现的语句。在这种情况下,您将从该
If
语句返回
null
,并将其乘以出现的下一个
If
语句的返回值

对于
Module
来说,语法是:
Module[{localvars},ReturnValue]

这意味着最后一条没有分号的语句就是ReturnValue。例如,下面的模块:

Module[{y},
   y = x * x;
   If[x < 0, -y, +y]
]

关于您的
模块
,我认为这可能是您想要实现的目标:

getAngleAttack[offset_] := 
 Module[{bounce1x, l1a, lightSlope, panelSlope}, 
  light[x_] = light'[x] (x - offset) + panel[interval];
  DumpVar[offset];

  lightSlope = N[light'[offset]];
  u1S = light'[offset];
  u1[x_] = (u1S (x - offset)) + panel[interval];

  bounce1x = 
   x /. N[NSolve[u1[x] == panel[x] && x < interval && x > -interval, 
      x]];

  u1r[x_] = panel'[bounce1x] (x - bounce1x) + panel[bounce1x];

  If[Length[bounce1x] > 0,
   bounce1x = bounce1x[[1]],
   bounce1x = offset];

   If[bounce1x > -interval && bounce1x < interval,

   lightSlope = N[u1'[bounce1x]];

   If[x <= 0,
    panelSlope := N[panelCoeff],
    panelSlope := -N[panelCoeff]];

   DumpVar[lightSlope];
   DumpVar[panelSlope];

   l1a = N[
     ArcTan[(lightSlope - panelSlope)/(1 + (panelSlope lightSlope))]];

   DumpVar[l1a];
   Return[l1a]
  ];
  l1a]

为了避免这种情况,请在
模块的开头定义任何用作局部变量的变量。
模块[{a,b,c,d},…]
我想添加一些内容

首先,分号是一种构建方式,正如Mike所指出的,分号抑制了前面语句的输出。但是,分号最有用的是允许您将多个表达式链接在一起,其中只需要一个表达式,就像您正在做的
模块
的主体一样。但是,分号对si很有用更简单的事情,比如这个人为的例子

a = 5;
b = (Print[a]; a - 3)
请注意,括号;
的优先级低于
=
,因此

b = Print[a]; a - 3
将b设置为
Print
的返回值,即
Null

为了将舍尔德的话融入他的评论中

b = (Print[a]; a - 3)
被解释为

Set[b, CompoundExpression[ Print[a], a - 3] ]
CompoundExpression[ Set[b, Print[a]], a - 3]
而第二种不正确的形式被解释为

Set[b, CompoundExpression[ Print[a], a - 3] ]
CompoundExpression[ Set[b, Print[a]], a - 3]
如果要查看表达式的形式,请使用它来显示表达式的内部形式。在检查其形式之前,如果不希望执行任何操作,则需要使用它,如使用
Set

其次,当使用
If
表达式将变量转换为不同的值时,它可以从
If
语句中取出,如下所示

 bounce1x = If[Length[bounce1x] > 0, bounce1x[[1]], offset];
因为
If
将返回
bounce1x[[1]]
offset
。这可以极大地简化表达式。这也适用于(
:=
),例如
面板坡度

panelSlope := If[x <= 0, N[panelCoeff], -N[panelCoeff]];
甚至

panelSlope = If[x<=0, 1, -1] N[panelCoeff];

panelSlope=If[x-interval&&bounce1x
条件未满足,则未输入设置它的
If
语句。因此,它将返回形式为
l1a$##
的内容,其中
###
是数字。此外,我将去掉
返回[l1a]
在该
If
语句中,由于没有必要,因此在
If
语句中设置了
l1a

我必须解决这个问题,但在命名变量时要小心。你所说的
light[x]=light'[x](x-offset)+panel[interval]的意思并不明显
@yoda:还有一些其他问题。模块的下面是一堆问题。我将发布一个带有注释的答案。我添加了一些注释以进一步简化/解释一些要点。谢谢!我在理解语法方面遇到了困难,特别是在每行都有分号的编程语言中。:-)如果您想做某事但不返回值,则必须在此处使用分号。Mathematica中分号的语义是抑制语句的返回值,而不是返回
null
。因此,从某种意义上讲,几乎每一行都需要分号。@Geekgirl现在也许是一个很好的时机来说明“;”实际上与e一样Mathematica中的所有其他内容都是一个函数。在这种情况下,函数
复合表达式
,其中
a;b
相当于
复合表达式[a,b]
a;b;
相当于
复合表达式[a,b,Null]
@SjoerdC.deVries,比我快。我写了一个更详细的答案,其中包括了这一点。@Sjoerd,对不起,我对“e”之前的“o”规则的熟悉程度不如对“e”之前的“I”规则的熟悉程度。:)非常感谢你提供了这样一个有帮助和彻底的答案!这正是我所缺少的信息。:-)
panelSlope = (1 - 2 UnitStep[x]) N[panelCoeff];
panelSlope = If[x<=0, 1, -1] N[panelCoeff];