Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Two months ago,I written a function IRobot to caculate the $I_{xx},I_{yy},I_{zz}$ and $I_{xy},I_{xz},I_{yz}$,shown as below:

  IRobot[IStyle_String, ρ_, VaribleRange_List] := Module[
   {IRobotResult},
    IRobotResult =
    Which[
        IStyle == "xx", Integrate[ρ (y^2 + z^2),
          {z, VaribleRange[[1, 1]], VaribleRange[[1, 2]]}, 
          {y, VaribleRange[[2, 1]], VaribleRange[[2, 2]]},
          {x, VaribleRange[[3, 1]], VaribleRange[[3, 2]]}],
        IStyle == "yy", Integrate[ρ (x^2 + z^2),
          {z, VaribleRange[[1, 1]], VaribleRange[[1, 2]]}, 
          {y, VaribleRange[[2, 1]], VaribleRange[[2, 2]]}, 
          {x, VaribleRange[[3, 1]], VaribleRange[[3, 2]]}],
        IStyle == "zz", Integrate[ρ (x^2 + y^2),
          {z, VaribleRange[[1, 1]], VaribleRange[[1, 2]]},
          {y, VaribleRange[[2, 1]], VaribleRange[[2, 2]]},
          {x, VaribleRange[[3, 1]], VaribleRange[[3, 2]]}],
        IStyle == "xy", Integrate[ρ x y,
           {z, VaribleRange[[1, 1]], VaribleRange[[1, 2]]},
           {y, VaribleRange[[2, 1]], VaribleRange[[2, 2]]}, 
           {x, VaribleRange[[3, 1]], VaribleRange[[3, 2]]}],
        IStyle == "xz", Integrate[ρ x z,
           {z, VaribleRange[[1, 1]], VaribleRange[[1, 2]]}, 
           {y, VaribleRange[[2, 1]], VaribleRange[[2, 2]]},
           {x, VaribleRange[[3, 1]], VaribleRange[[3, 2]]}],
       IStyle == "yz", Integrate[ρ y z,
           {z, VaribleRange[[1, 1]], VaribleRange[[1, 2]]}, 
           {y,VaribleRange[[2, 1]], VaribleRange[[2, 2]]},
           {x,VaribleRange[[3, 1]], VaribleRange[[3, 2]]}]
    ]
  ]

And I can use it correctly.

 IRobot["xx", ρ, {{-h1, 0}, {-r1, r1}, {-L1 - Sqrt[r1^2 - y^2], Sqrt[r1^2 - y^2]}}]
 (*===>*)
 1/12 h1 r1 (4 h1^2 (2 L1 + \[Pi] r1) + r1^2 (8 L1 + 3 \[Pi] r1)) ρ

However,I would like to simplify my code by Similarity,my trail as below:

 Flatten /@Thread@List[{z, y, x},
   Apply[Part[VaribleRange, ##] &, Table[{i, j}, {i, 1, 3}, {j, 1, 2}], {2}]]
(*==>*)
 {{z, VaribleRange[[1, 1]], VaribleRange[[1, 2]]},
  {y, VaribleRange[[2, 1]], VaribleRange[[2, 2]]},
  {x, VaribleRange[[3, 1]], VaribleRange[[3, 2]]}}

Trial 1

IRobot[IStyle_String, ρ_, VaribleRange_List] := Module[
   {IRobotResult,intlist},
   intlist=
    Flatten /@Thread@List[{z, y, x},
   Apply[Part[VaribleRange, ##] &, Table[{i, j}, {i, 1, 3}, {j, 1, 2}], {2}]];
    IRobotResult =
    Which[
        IStyle == "xx", Integrate[ρ (y^2 + z^2),intlist],
        IStyle == "yy", Integrate[ρ (x^2 + z^2),intlist],
        IStyle == "zz", Integrate[ρ (x^2 + y^2),intlist],
        IStyle == "xy", Integrate[ρ x y,intlist],
        IStyle == "xz", Integrate[ρ x z,intlist],
        IStyle == "yz", Integrate[ρ y z,intlist]
    ]
  ]

Unfortunately,it failed.

Trail2

 IRobot[IStyle_String, ρ_, VaribleRange_List] := Module[
   {IRobotResult,intlist},
   intlist[z_,y_,x_,range_]:=
    Flatten /@Thread@List[{z, y, x},
   Apply[Part[range, ##] &, Table[{i, j}, {i, 1, 3}, {j, 1, 2}], {2}]];
    IRobotResult =
    Which[
        IStyle == "xx", Integrate[ρ (y^2 + z^2),intlist[z,y,x,VaribleRange]],
        IStyle == "yy", Integrate[ρ (x^2 + z^2),intlist[z,y,x,VaribleRange]],
        IStyle == "zz", Integrate[ρ (x^2 + y^2),intlist[z,y,x,VaribleRange]],
        IStyle == "xy", Integrate[ρ x y,intlist[z,y,x,VaribleRange]],
        IStyle == "xz", Integrate[ρ x z,intlist[z,y,x,VaribleRange]],
        IStyle == "yz", Integrate[ρ y z,intlist[z,y,x,VaribleRange]]
    ]
  ]

Also it ends in failure!

Or

I want to by

 Which@@(
 Flatten@{IStyle == #1, Integrate[ρ #2, intlist[z,y,x,VaribleRange]]} & @@@
 {{"xx", (y^2 + z^2)}, {"yy", (x^2 + z^2)}, {"zz", (x^2 + y^2)},
  {"xy", x y}, {"xz", x z}, {"yz", y z}})
  (*==>*)

enter image description here

to achieve

  Which[
        IStyle == "xx", Integrate[ρ (y^2 + z^2),intlist[z,y,x,VaribleRange]],
        IStyle == "yy", Integrate[ρ (x^2 + z^2),intlist[z,y,x,VaribleRange]],
        IStyle == "zz", Integrate[ρ (x^2 + y^2),intlist[z,y,x,VaribleRange]],
        IStyle == "xy", Integrate[ρ x y,intlist[z,y,x,VaribleRange]],
        IStyle == "xz", Integrate[ρ x z,intlist[z,y,x,VaribleRange]],
        IStyle == "yz", Integrate[ρ y z,intlist[z,y,x,VaribleRange]]
    ]

So my question is why and how to revise it.

share|improve this question

1 Answer 1

up vote 4 down vote accepted

Proposal

I recommend something like this:

IRobot2[IStyle_String, ρ_, VaribleRange_List] :=
  Block[{x, y, z},
    With[{expr = 
     Switch[IStyle,
       "xx", (y^2 + z^2),
       "yy", (x^2 + z^2), 
       "zz", (x^2 + y^2),
       "xy", x y,
       "xz", x z,
       "yz", y z
     ]},
     Integrate[ρ expr, ##] & @@ Join[{{z}, {y}, {x}}, VaribleRange, 2]
    ]
  ]

The Block is there to localize x, y, z to prevent these Symbols from incorrectly evaluating while they are manipulated, before passing them to Integrate using SlotSequence and Apply.


Code review

I first posted my recommendation above because it is faster for me to do so than to analyze and debug your attempts that did not work but as requested I will do the latter now.

The Trial 1 code throws this error when used:

Integrate::ilim: Invalid integration variable or limit(s) in {{z,-h1,0},{y,-r1,r1},{x,-L1-Sqrt[r1^2-Power[<<2>>]],Sqrt[r1^2-y^2]}}. >>

That should draw your attention to that part of the code, meaning intlist and how it is used in Integrate. The problem arises because intlist is (indeed) a list, whereas the parameters of Integrate need to be a sequence, i.e. 1, 2, 3 rather than {1, 2, 3}. In my own code above I used SlotSequence for this because it is more universal and I could not remember off-hand the way in which Integrate evaluated its arguments. However your Trial 1 code can be corrected by wrapping the existing right-hand-side definition of intlist in Sequence @@ ( . . . ), or a bit more concisely:

intlist = Sequence @@ (
  Flatten /@ Thread@{ {z, y, x}, Array[VaribleRange[[##]] &, {3, 2}] }
 )

I stated that using SlotSequence is more robust. Here is an example where it is needed:

iterSeq = Sequence[{x, 5}, {i, x}];
Table[x + i^2, iterSeq]              (*failure*)

iterList = {{x, 5}, {i, x}} ;
Table[x + i^2, ##] & @@ iterList     (*success*)

(Attributes[Table] includes HoldAll and iterSeq is not evaluated.)

Trial 2 can be corrected in the same manner.

The second attempt at Trial 2 was clever but you didn't quite get it right. Which needs input in the form of:

Which[
  test1, value1,
  test2, value2,
  . . .
]

While your code results in:

Which[
  {test1, value1},
  {test2, value2},
  . . .
]

Also you are not doing anything to Hold the "value" expressions, therefore Integrate will evaluate prematurely.

To correct these problems we need to Flatten the entire expression, not the sub-lists, and we need to add expression holding:

Which @@ Flatten[
 {IStyle == #1, Unevaluated @ Integrate[ρ #2, intlist[z, y, x, VaribleRange]]} & @@@
   {{"xx", (y^2 + z^2)},
    {"yy", (x^2 + z^2)},
    {"zz", (x^2 + y^2)},
    {"xy", x y},
    {"xz", x z},
    {"yz", y z}}
]

Unevaluated should suffice here (I did not actually test this section of code) but if not you could use Hold in its place, then add a ReleaseHold outside of Which.

share|improve this answer
    
♦,+1,Perfect!This solution make the function IRobot become more refine and elegant.By the way,I would like to why my trail cannot work normally or can you give me some suggestion about writing program.Thanks sincerely! –  auto Jul 10 at 8:11
1  
@tangshutao Comment again on this answer some time tomorrow to remind me, and I'll try to explain where your attempt went wrong. I need to sleep now. –  Mr.Wizard Jul 10 at 8:18
    
♦,Ok,thanks ror your warm help.May you have a good dream! –  auto Jul 10 at 8:26
1  
@tangshutao Update complete. –  Mr.Wizard Jul 10 at 19:18
    
♦.Wow,Thanks very much.From your reputation rank,I know you are a Mathematica expert!! –  auto Jul 11 at 0:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.