RE: Can anyone simplify this?
- To: mathgroup at smc.vnet.net
- Subject: [mg36479] RE: [mg36461] Can anyone simplify this?
- From: "DrBob" <drbob at bigfoot.com>
- Date: Sun, 8 Sep 2002 03:31:11 -0400 (EDT)
- Reply-to: <drbob at bigfoot.com>
- Sender: owner-wri-mathgroup at wolfram.com
Expanding on my earlier simplification of the Moran Research code, I studied the problem a little more and found another useful Rule and a Rule that should help but doesn't. Maybe somebody can explain what I'm doing wrong on that one. My earlier result (after applying rule1, ... rule7) had the following as third element of a List in the definition of f: Which[ Ca == 0 && Cb == 0, "Nil", Z1 == Z2 && Ca < 0, Aa, Z1 == Z2 && Cb < 0, Ab, (Z1 == Z2 && Ca > 0) && Aa > 90, Aa - 90, Z1 == Z2 && Ca > 0, Aa + 90, Z1 == Z2 && (Cb > 0 && Ab > 90), Ab - 90, Z1 == Z2 && Cb > 0, Ab + 90, Z1 == Z2, Null, Aa == Ab, Aa, Ca == 0 && Cb == 0, "Nil", Ca == 0, Ab, Cb == 0, Aa, Y == 0, "Nil", X > 180, X - 180, X < 0, X + 180, True, X] Several things occurred to me in terms of simplifying this. The first was that the last six arguments of Which could be replaced with two, as follows: Which[ Ca == 0 && Cb == 0, "Nil", Z1 == Z2 && Ca < 0, Aa, Z1 == Z2 && Cb < 0, Ab, (Z1 == Z2 && Ca > 0) && Aa > 90, Aa - 90, Z1 == Z2 && Ca > 0, Aa + 90, Z1 == Z2 && (Cb > 0 && Ab > 90), Ab - 90, Z1 == Z2 && Cb > 0, Ab + 90, Z1 == Z2, Null, Aa == Ab, Aa, Ca == 0 && Cb == 0, "Nil", Ca == 0, Ab, Cb == 0, Aa, Y == 0, "Nil", True,Mod[X,180]] This probably has no advantage other than clarity, but that's worth something. I wrote a rule that should do this when applied before all the others: rule8 = dummyIf[a_ > b_, a_ - b_, dummyIf[a_ < 0, a_ + b_, a_]] :> Mod[a, b]; but it had no effect on the expression. Apparently there was no match, and I can't see why. The second thing I noticed was that the condition Ca == 0 && Cb == 0 occurs twice in the Which statement. The following rule fixes that kind of situation: rule9 = dummyWhich[a___, b_, c_, d__, b_, e_, f__] /; EvenQ[Length[List[a]]] && EvenQ[Length[List[d]]] && EvenQ[Length[List[f]]] :> dummyWhich[a, b, c, d, f]; expr //. {rule1, rule2, rule3, rule4, rule5, rule6, rule7, rule9} The third thing I noticed was the treatment of Aa and Ab. The expressions If[Aa > 90, Aa - 90, Aa + 90] If[Ab > 90, Ab - 90, Ab + 90] in the original expression may be equivalent (depending on what's known about Aa and Ab a priori) to: Mod[Aa+90,180] Mod[Ab+90,180] If that is a valid assumption in the situation (no way for me to know), the expression is now Which[ Ca == 0 && Cb == 0, "Nil", Z1 == Z2 && Ca < 0, Aa, Z1 == Z2 && Cb < 0, Ab, Z1 == Z2 && Ca > 0, Mod[Aa + 90, 180], Z1 == Z2 && Cb > 0, Mod[Ab + 90, 180], Z1 == Z2, Null, Aa == Ab, Aa, Ca == 0, Ab, Cb == 0, Aa, Y == 0, "Nil", True, Mod[X, 180]] The next thing I notice is that the sixth condition, Z1==Z2, which results in Null if found True, isn't needed. If Z1==Z2 then one of the first five conditions is also true, so execution wouldn't get that far. Hence we can delete that condition-response pair. Finally, I'm stopping with this: Which[ Ca == 0 == Cb, "Nil", Z1 == Z2 && Ca < 0, Aa, Z1 == Z2 && Cb < 0, Ab, Z1 == Z2 && Ca > 0, Mod[Aa + 90, 180], Z1 == Z2 && Cb > 0, Mod[Ab + 90, 180], Aa == Ab, Aa, Ca == 0, Ab, Cb == 0, Aa, Y == 0, "Nil", True, Mod[X, 180]] I have no idea what you're actually doing with this code, but it looks weird even AFTER I've simplified it. Bobby Treat -----Original Message----- From: DrBob [mailto:drbob at bigfoot.com] To: mathgroup at smc.vnet.net Subject: [mg36479] RE: [mg36461] Can anyone simplify this? If I haven't missed a step, the following should work nicely -- best done before defining any of the symbols that appear: Attributes[dummyIf] = HoldAll; Attributes[dummyWhich] = HoldAll; expr = {If[Aa == Ab, a Sa + b Sb, If[Ca == 0 || Cb == 0, a Sa + b Sb, SS]], \ If[Aa == Ab, a Ca + b Cb, If[Ca == 0 || Cb == 0, a Ca + b Cb, CC]], If[Ca == 0 && Cb == 0, "Nil", If[Z1 == Z2, If[Ca < 0, Aa, If[Cb < 0, Ab, If[Ca > 0, If[Aa > 90, Aa - 90, Aa + 90], If[Cb > 0, If[Ab > 90, Ab - 90, Ab + 90]]]]], If[Aa == Ab, Aa, If[Ca == 0 && Cb == 0, "Nil", If[ Ca == 0, Ab, If[Cb == 0, Aa, If[Y == 0, "Nil", If[X > 180, X - 180, If[X < 0, X + 180, X]]]]]]]]]} /. {If -> dummyIf}; rule1 = dummyIf[a_, b_, dummyIf[c_, d_, e_]] -> dummyWhich[a, b, c, d, True, e]; rule2 = dummyIf[a_, dummyIf[ b_, c_, d_], e_] -> dummyWhich[a && b, c, a, d, True, e]; rule3 = dummyIf[a_, dummyIf[b_, c_, d_]] -> dummyWhich[a && b, c, a, d]; rule4 = dummyWhich[a__, b_, dummyIf[c_, d_, e_], f___] -> dummyWhich[a, b && c, d, b, e, f]; rule5 = dummyWhich[a__, b_, dummyWhich[c_, d_, e___], f___] -> dummyWhich[a, b && c, d, b, dummyWhich[e], f]; rule6 = dummyWhich[] :> Null; rule7 = HoldPattern[True && a_] :> a; expr //. {rule1, rule2, rule3, rule4, rule5, rule6, rule7} /. {dummyWhich -> Which The result of that last line is: {Which[Aa == Ab, a Sa + b Sb, Ca == 0 || Cb == 0, a Sa + b Sb, True, SS], Which[Aa == Ab, a Ca + b Cb, Ca == 0 || Cb == 0, a Ca + b Cb, True, CC], Which[Ca == 0 && Cb == 0, "Nil", Z1 == Z2 && Ca < 0, Aa, Z1 == Z2 && Cb < 0, Ab, (Z1 == Z2 && Ca > 0) && Aa > 90, Aa - 90, Z1 == Z2 && Ca > 0, Aa + 90, Z1 == Z2 && (Cb > 0 && Ab > 90), Ab - 90, Z1 == Z2 && Cb > 0, Ab + 90, Z1 == Z2, Null, Aa == Ab, Aa, Ca == 0 && Cb == 0, "Nil", Ca == 0, Ab, Cb == 0, Aa, Y == 0, "Nil", X > 180, X - 180, X < 0, X + 180, True, X]} I've used Null where that would be the result of your original logic -- maybe you want it to be "Nil". Or maybe you want to use Null instead of "Nil". Your choice. Wherever you see Null, there's possibly a case you haven't covered. Bobby Treat -----Original Message----- From: Moranresearch at aol.com [mailto:Moranresearch at aol.com] To: mathgroup at smc.vnet.net Subject: [mg36479] [mg36461] Can anyone simplify this? I have substituted the letters SS, CC, X, Y and Z1 and Z2 for some complicated expressions just to illustrate the form of the function. This function works and all the conditions are necessary but I am sure a more elegant programming solution perhaps using While could be found. Any suggestions to tighten this up? Thank you. f[{Sa_, Ca_, Aa_, Sb_, Cb_, Ab_, a_, b_}] := {If[Aa == Ab, a Sa + b Sb, If[Ca == 0 || Cb == 0, a Sa + b Sb, SS]], If[Aa == Ab, a Ca + b Cb, If[Ca == 0 || Cb == 0, a Ca + b Cb, CC]], If[Ca == 0 && Cb == 0, "Nil", If[Z1 == Z2, If[Ca < 0, Aa, If[Cb < 0, Ab, If[Ca > 0, If[Aa > 90, Aa - 90, Aa + 90], If[Cb > 0, If[Ab > 90, Ab - 90, Ab + 90]]]]], If[Aa == Ab, Aa, If[Ca == 0 && Cb == 0, "Nil", If[Ca == 0, Ab, If[Cb == 0, Aa, If[Y == 0, "Nil", If[X > 180, X - 180, If[X < 0, X + 180, X]]]]]]]]]}