0

I have here a complicated bit of code that is not pretty nor easy to follow, but it represents a simplification of a larger body of code I am working with. I am a Mathematica novice and have already received some help on this issue from stackoverflow but it is still not solving my problem. Here is the code for which I hope you can follow along and assume what I am trying to get it to do. Thanks to you programming whizzes for the help.

a[b_, c_] = -3*b + 2*c + d + e + f;

g[b_, c_] := If[a[b, c] < 0, -3*a[b, c], a[b, c]];

h[T_, b_, c_] = (T/g[b, c]);

i[h_, T_, b_, c_] := If[h[T, b, c] > 0, 4*h[T, b, c], -5*h[T, b, c]];

j[b_, c_] := If[a[b, c] < 0, 5*a[b, c], 20*a[b, c]];

XYZ[h_, T_, i_, g_, j_, b_, c_] = T*i[h, T, b, c]*g[b, c] + j[b, c]

rules = {a -> 1, b -> 2, c -> 3, d -> 4, e -> 5, f -> 6, T -> 10};

XYZ[h, T, i, g, j, b, c] //. rules
Community
  • 1
  • 1
ZB18749
  • 49
  • 1
  • 6
  • What exactly is the question? I think you should explain what you are trying to do and where you believe the error lies. – Orbling May 24 '11 at 22:45
  • 1
    Also, as you refer to the [previous question](http://stackoverflow.com/questions/6115806/assistance-with-mathematica-using-replace-method-with-if-conditional), it is wise to refer to it. – Orbling May 24 '11 at 22:45
  • The goal is to get a numeric output for XYZ after replacing all the variables, however the above code does not work. – ZB18749 May 24 '11 at 22:50
  • 1
    Last entry of the `rules` list, did you mean to have `T -> 10`? – Orbling May 24 '11 at 22:56
  • 2
    Also the first rule a->1 doesn't make sense, since you also defined a function with that name, whose head will now be replaced by 1. After getting rid of that rule the expression evaluates to a numeric value. – Thies Heidecke May 24 '11 at 23:07
  • `If` should be used for programming/procedural code, while for mathematical functions it is best to use [Piecewise](http://reference.wolfram.com/mathematica/ref/Piecewise.html). Your code defining the functions `i` and `XYZ` is probably not what you really want - e.g. I don't think you want to be using any function other than `h` in `i`. Finally, using the `rules` to put values in `XYZ` seems a little perverse since you could pass the values straight to it. – Simon May 25 '11 at 03:55
  • The use of j in the definition of XYZ doesn't make sense. Because there is already a function named j AND because you are using Set (=) instead of SetDelayed (:=) the j in the right hand side of the definition is replaced with the earlier definition of j, so the j in the argument list doesn't refer to anything anymore. Compare with this: In ==> `fun1[i_] := Sin[i]` In ==> `fun2[fun1_, x_] = fun1[x]` In ==> `fun2[ape, y]` Out ==> `Sin[y]` In ==> `fun2[nut, y]` Out ==> `Sin[y]` – Sjoerd C. de Vries May 25 '11 at 08:36
  • So, my advice is to use := there, or better, if you do not plan to use various function names as arguments to avoid using them in the definition of XYZ (and i[ ], where you do the same, but where you use SetDelayed) – Sjoerd C. de Vries May 25 '11 at 08:46
  • Thanks to all of you for help, my apologies for being such an idiot with coding. I went to school to study chemistry and I've never been very good with foreign languages. Most of what was said above is Greek to me, but I am learning. This is really a great website. – ZB18749 May 25 '11 at 13:22

1 Answers1

2

Preserving as much of your code as possible, it will work with just a few changes:

a[b_, c_] := -3*b + 2*c + d + e + f;

g[b_, c_] := If[# < 0, -3 #, #] & @ a[b, c]

h[T_, b_, c_] := T / g[b, c]

i[h_, T_, b_, c_] := If[# > 0, 4 #, -5 #] & @ h[T, b, c]

j[b_, c_] := If[# < 0, 5 #, 20 #] & @ a[b, c]

XYZ[h_, T_, i_, g_, j_, b_, c_] := T*i[h, T, b, c]*g[b, c] + j[b, c]

rules = {a -> 1, b -> 2, c -> 3, d -> 4, e -> 5, f -> 6, T -> 10};

XYZ[h, T, i, g, j, b, c] /. rules

(* Out= 700 *)
  1. If statements are again externalized, as in the last problem.

  2. all definitions are made with SetDelayed (:=), as a matter of good practice.

  3. The presumed error T - 10 in your rules is corrected to T -> 10

Notice that again ReplaceRepeated (//.) is not needed, and is changed to /.

We still have a nonsensical rule a -> 1 but it does not cause a failure.

Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
  • Thanks Mr. Wizard! This helped immensely! I now know how to use the # symbol. – ZB18749 May 25 '11 at 13:23
  • @ZB18749 I am glad that helps. I recommend skimming [Leonid Shifrin's online book](http://www.mathprogramming-intro.org/book/Book.html) to learn about Mathematica. Also, if are not already doing it, you can select a name or symbol and press F1 to get more information about. For example, if you select `&` in the code and press F1, one of the results is `Function`. – Mr.Wizard May 25 '11 at 13:32
  • @ZB18749, something else, as a new Mathematica user, even if your code works, it is unlikely to be optimal. At some point you may want to post a working application along with a description of what it does to this sister site: http://codereview.stackexchange.com/ to get feedback on your methods. – Mr.Wizard May 25 '11 at 13:37
  • Mr. Wizard, after reading the first chapter of Leonid's book, I am convinced that Mathematica is a far more powerful tool than I initially realized, while maintaining a fairly simplistic coding language. – ZB18749 May 25 '11 at 14:54
  • I have one last and final question in regards to the above piece of code you wrote that works. I want to substitute `b->1-c` into `rules = {b -> 1 - c, c -> 3, d -> 4, e -> 5, f -> 6, T -> 10};` but when I evaluate `XYZ[h, T, i, g, j, b, c] /. rules` the resulting output is not numeric. Is there an easy way to make the variable `b` in `XYZ[h, T, i, g, j, b, c]` equal to '1-c' and still have it evaluate for a given value of 'c' ? Thanks again – ZB18749 May 25 '11 at 14:54
  • @ZB18749, that would be a time to use either `ReplaceRepeated` (`//.`) or serial replacement (`/. b -> 1-c /. rules`). This is needed because one rule relies upon another, and therefore a single replacement pass cannot accomplish your intent. – Mr.Wizard May 25 '11 at 17:25