I am new to Mathematica, and using a Module to perform a procedure, then return a value. However, Mathematica seems to be evaluating and returning symbolic values instead of the numerical value I want.
Questions I have are: When don't you use semicolons? And when do you use Return[value] instead of just writing "value"?
DumpVar[x_] := Print[ToString[HoldForm[x]], ":", x];
SetAttributes[DumpVar, {Listable, HoldAll}]
width = 1;
interval = width/2;
panelCoeff = 2;
lightAngle = Pi/3;
(*Panel and light equations*)
panel[x_] = Abs[panelCoeff x];(*panelCoeff ((x)^2);*)
light[x_] = Tan[lightAngle]*x;
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];
l1a
Return[l1a]
]
Return[l1a];
];
myint = getAngleAttack[0];
(*myint = N[f[10]];*)
DumpVar[myint];
Plot[{panel[x], light[x]}, {x, -.6, .6}]
myint = getAngleAttack[.5];
DumpVar[myint];
My goal is to be able to graph and integrate this function.
In the middle of your block you have:
If[Length[bounce1x] > 0,
bounce1x = bounce1x[[1]];,
bounce1x = offset;
]
The format of If
is as follows: If[Condition, ValueIfTrue, ValueIfFalse]
So If[True, 3, 2]
returns 3, and If[False, 3, 2]
returns 2. Your semicolons here are unnecessary, but you do need one at the end of the if statement:
If[Length[bounce1x] > 0,
bounce1x = bounce1x[[1]],
bounce1x = offset
];
Otherwise, Mathematica will interpret that as multiplication of that statement times whatever the next one to show up will be. In this case, you're returning null
from that If
statement, and it's being multiplied by the return value of the next If
statement that comes up.
For Module
the syntax is: Module[{localvars}, ReturnValue]
Which means whatever is the last statement that shows up without a semicolon is the ReturnValue. So for example the following module:
Module[{y},
y = x * x;
If[x < 0, -y, +y]
]
will return -y when x < 0, and +y otherwise. The one exception this is when Return
shows up. Just like in most languages, you can return early from a function by using Return
:
Module[{y},
y = x * x;
If[x < 0,
Return[-y],
Return[+y]];
(* We never reach this point to return null *)
];
With respect to your Module
, I think this may be what you're trying to accomplish:
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]
Another thing you should watch out for is any variables you use inside of a Module
. If you run the following piece of code, you'll get 4, -113/5, 32
as the output values:
d = 4 (* d was 4 *)
Module[{a, b, c},
a = 3;
b = 2;
c = 5;
d = 32; (* Uh oh! I just overwrite whatever d was *)
a^2 + b / c - d]
d (* d is now 32 *)
To avoid this, define any variables you're using as local variables within the start of the Module
: Module[{a, b, c, d}, ...]